关于多线程的原子量的问题,希望大家一起讨论下,求结论
废话不多说,直接来代码,两个类
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
public class MyCountA implements Runnable
{
private static AtomicLong along = new AtomicLong(10000); //为什么这里要加static
private String name;
private int x;
private Lock lock;
public MyCountA(String name,int x,Lock lock)
{
this.name=name;
this.x=x;
this.lock=lock;
}
public void run(){
lock.lock();
System.out.println(name+"操作金额:"+x+"账户余额:"+along.addAndGet(x));
lock.unlock();
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestM
{
public static void main(String[] args)
{
Lock lock = new ReentrantLock(false);
ExecutorService pool = Executors.newCachedThreadPool();
Runnable t1 = new MyCountA("张三", 1000,lock);
Runnable t2 = new MyCountA("李四", -1000,lock);
Runnable t3 = new MyCountA("王五", 5000,lock);
Runnable t4 = new MyCountA("赵六", -6000,lock);
Runnable t5 = new MyCountA("阿大", 8000,lock);
Runnable t6 = new MyCountA("阿三", -9000,lock);
pool.execute(t6);
pool.execute(t5);
pool.execute(t4);
pool.execute(t3);
pool.execute(t2);
pool.execute(t1);
pool.shutdown();
}
}
加static的话输出的答案正确:
阿三操作金额:-9000账户余额:1000
阿大操作金额:8000账户余额:9000
赵六操作金额:-6000账户余额:3000
张三操作金额:1000账户余额:4000
王五操作金额:5000账户余额:9000
李四操作金额:-1000账户余额:8000
不加static的话就得不到正确答案:
阿三操作金额:-9000账户余额:1000
阿大操作金额:8000账户余额:18000
赵六操作金额:-6000账户余额:4000
李四操作金额:-1000账户余额:9000
王五操作金额:5000账户余额:15000
不加的话每个人的操作全是针对10000这个值而言的,不知道是锁没有生效,这几个线程都在别的线程还没改变10000这个值的时候做的操作,还是每个线程对along 的值的修改无法对其他线程生效,还有就是原子量有什么用(说是可以保证变量操作的原子性,但整个程序还需要考虑线程安全的。)也就是在这里用原子量和普通的long 是没什么区别的,求达人解答
------解决方案--------------------
你这问题跟多线程无关,
就是static变量的事,
static变量是属于类的,不是某一个对像,也就是所有对像共用的变量,
非static就是一个对像一个
------解决方案--------------------
------解决方案--------------------
static 变量属于 类级的
------解决方案--------------------这里是要加锁的,不加锁可能有两个线程同时执行,第二个线程执行along.addAndGet(),就把第一个线程的值改掉了。
至于为什么要加private static AtomicLong along
如果不加的话,t1,t2...都是不同的MyCountA对象,那么操作的就是不同的along 变量了,加了static就是操作的同一个。
------解决方案--------------------你们讨论我学习
------解决方案--------------------因为Java的long不是C++的long,现在大多数C++的编译器,long是4个字节。
而Java的long是8个字节。那么32位的OS,一个指令最多处理4个字节。
也就说你 long a = 1;其实操作了两次,那么这两次就有可能被多线程cut。
所以一定要把 long当做一个原子量来操作。
幸好Java的lib提供了AtomicLong 。
就这么回事。