线程共享实例变量

时间:2013-08-31 23:49:38

标签: java multithreading synchronized

我希望两个线程共享变量,但有时在运行时它会输出两次,而不是1和2。

public class man implements Runnable{

    int value = 0;

    public static void main(String[] args){
        Runnable job = new man();
        Thread work1 = new Thread(job);
        work1.setName("Thread1");
        Thread work2 = new Thread(job);
        work2.setName("Thread2");

        work1.start();
        work2.start();
    }


    public void run(){
        synchronized(this){
            value = value + 1;
        }
        System.out.println("VALUE = " + value +", Running " + Thread.currentThread().getName());
    }



}

输出有时是:

VALUE = 2, Running Thread2
VALUE = 2, Running Thread1

和其他时间是:

VALUE = 1, Running Thread2
VALUE = 2, Running Thread1

为什么会这样?我正在HeadFirst书中学习Java,这个问题出现了。

2 个答案:

答案 0 :(得分:3)

您未在System.out.println来电中同步访问权限,因此偶尔会出现" second"第一个线程"之前的线程增量打印。

答案 1 :(得分:3)

您需要同步对变量的访问权限。

发生的事情是,两个线程都在读取变量的值后才读取变量的值。换句话说:

  1. 主题1:同步(this)=>线程2无法进入自己的同步(this)
  2. 线程1:值=值+ 1; =>说1
  3. 线程1:结束同步块=>线程2可以进入自己的同步(现在)
  4. 线程2:同步(this)=>线程1无法进入自己的同步(this)
  5. 主题2:value = value + 1; => 2
  6. 线程2:打印值,即2
  7. 线程1:打印值,即2
  8. 解决方案是在System.out.println("VALUE = " + value +", ...);块内移动synchronized。这迫使上述序列重新排序为:

    1. 主题1:同步(this)=>线程2无法进入自己的同步(this)
    2. 线程1:值=值+ 1; =>说1
    3. 线程1:打印值,即1
    4. 线程1:结束同步块=>线程2可以进入自己的同步(现在)
    5. 线程2:同步(this)=>线程1无法进入自己的同步(this)
    6. 主题2:value = value + 1; => 2
    7. 线程2:打印值,即2