美文网首页
一个多线程的小问题(对象同步)

一个多线程的小问题(对象同步)

作者: c7d122ec46c0 | 来源:发表于2017-04-13 17:41 被阅读0次

    话不多,直接上代码,去年刚学java时发现的一个问题,现在看起来居然还懵了一会,所以记录下

    public class TestSynconnized {
        private Object object = new Object();
        private volatile Integer i = 0;
        public void Add() {
            synchronized(i) {
                System.out.println("++i="+(++i)+Thread.currentThread().getName());
            }
        }    
        public static void main(String args[]) {
            TestSynconnized testSynconnized = new TestSynconnized();
            for (int i = 0; i < 20; i++) {
    
                Thread thread = new Thread(new Runnable() {
                    public void run() {
                        for (int i = 0; i < 1000; i++) {
                            testSynconnized.Add();    
                        }
                    }
                });
    
                thread.start();
            }
            while (Thread.activeCount() > 1) {
                Thread.yield();
            }
    
            System.out.println(testSynconnized.i);    
        }
    }
    

    运行这段代码发现并不是每次执行的结果都是20000,原因:在同步方法块中更新了锁对象,导致锁失效。
    在执行i++并退出同步方法块后,另一个持有原先的i对象锁的线程进入同步方法块。此时下一个线程运行到synchronized时锁条件已经变化,也可进入同步方法块,再次感谢知乎网友meantobe的解答,直接复制了答案

    修改方法

    public class TestSynconnized {
    
        private Object object = new Object();
        private volatile Integer i = 0;
        public synchronized void Add() {
            {
                System.out.println("++i="+(++i)+Thread.currentThread().getName());
            }
        }
        public static void main(String args[]) {
            TestSynconnized testSynconnized = new TestSynconnized();
            for (int i = 0; i < 20; i++) {
    
                Thread thread = new Thread(()-> {
                        for (int j = 0; j < 1000; j++) {
                            testSynconnized.Add();
                        }
                    }
                );
    
                thread.start();
            }
            while (Thread.activeCount() > 1) {
                Thread.yield();
            }
    
            System.out.println(testSynconnized.i);
        }
    
    }
    

    这段代码实际是从深入理解java虚拟机里面捞出来改的

    相关文章

      网友评论

          本文标题:一个多线程的小问题(对象同步)

          本文链接:https://www.haomeiwen.com/subject/auzbattx.html