for循环中的synchronized方法

时间:2015-02-11 21:13:15

标签: java multithreading synchronization synchronized

在下面的简单示例代码中(主要取自此nice udemy video),有两个线程通过synchronized方法递增计数实例变量。

然而,此方法位于每个线程的for循环内。

我的问题是:在这样的情况下,线程是否可能实际上将他们的调用混合到increment?例如:

  

线程1调用i = 0

的增量      

线程1调用i = 1

的增量      

线程2调用j = 0

的增量      

线程2调用j = 1

的增量      

线程1调用i = 2

的增量      

线程2调用增量为j = 2

     

......等等

我尝试过多次运行大ij,但它们总是顺序显示,即

  

线程1调用i = 0

的增量      

线程1调用i = 1

的增量      

线程1调用i = 2

的增量      

...线程1完成

     

线程2调用j = 0

的增量      

线程2调用j = 1

的增量      

...线程2完成

根据我对synchronized关键字的理解,第一种情况应该发生,所以我只是想知道我是否因为有可能存在其他我缺少的东西而看到第二种情况。

 public class SyncTest {

    private int count = 0;

    public static void main(String[] args) {
        SyncTest test = new SyncTest ();
        test.doWork();
    }

    public synchronized void increment(String threadName) {
        System.out.println("thread: " + threadName);
        count++;
    }

    public void doWork() {

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 100000; i++) {
                    increment("t1");
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public  void run() {
                for (int j = 0; j < 100000; j++) {
                    increment("t2");
                }
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch(InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Count is: " + count);
    }
}

1 个答案:

答案 0 :(得分:2)

  

基于我对synchronized关键字的理解,第一种情况应该发生,所以我只是想知道我是否因为有可能缺少其他东西而看到第二种情况。

您的理解是正确的。

事实上,当我运行您的确切代码时,我得到一系列t1 s后跟一系列t2 s,然后是t1 s,然后再t2等等。这清楚地表明线程正相互抢占,并且没有我们忽略的微妙的无意识同步。