-->

多线程访问成员变量

2019-07-05 09:39发布

问题:

请问为什么会打印一样的啊

回答1:

要用synchronized阻塞线程,操作temp和输出temp都要放在其中:

package ExecutorTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test1 {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
for (int i =0; i<100; i++){
service.execute(new Test2());
}
service.shutdown();
while (!service.isTerminated()){
}
// System.out.println(Test3.getInstance().temp);
}
}

class Test2 implements Runnable{

@Override
public void run() {
    Test3 test3 = Test3.getInstance();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    synchronized (test3){
        test3.temp = test3.temp +1;
        System.out.println(test3.temp);
    }
}

}

class Test3 {
private static Test3 t;
public volatile int temp = 128;

public static synchronized Test3 getInstance(){
    if(t == null){
        t = new Test3();
    }
    return t;
}

}



回答2:

锁呢.
...



回答3:

for 里面定义一个变量接收 new addNum():

for (int i = 0; i < 3000; i++)
{
    int j = new addNum();
    executorService.execute(j);
}


回答4:

线程1 从内存中拿到temp的值3127 正准备加工成3128 这时候线程2也来了
线程2也从内存中拿到了temp的值3127,准备把他加工成3128
这时候线程1已经把temp加工成3128,并存储到了内存中。
但是线程2已经从内存中拿过temp了,他看不到temp的变化,继续把3127加工成3128
把3128存储到内存中。所以结果是3128;

这时候需要加锁。
加锁,线程1 拿到temp 3127,准备加工
线程2 准备拿temp,看到有锁,知道有线程在加工,就先等待
线程1把temp加工成3128,存储到内存,释放锁,通知线程2
线程2收到锁释放信号,自己加锁,拿到temp,这时候的temp是3128
把temp加工成3129,存储到内存,释放锁。结果就是3129