使用同步方法获取对象锁定

这个问题在这里已经有了答案:

  • “同步”是什么意思? 15个答案
  • 使用同步方法而不是同步块有优势吗? 22个答案
  • Java同步方法锁定对象或方法? 10个答案

  • synchronized关键字的这种用法会导致该方法获取该方法被调用的对象的锁定。 由于您有5个MultiThr对象,这是5个不同的被锁定的对象。

    有很多选项可以解决这个问题,例如,您可以创建一个要在所有MultiThr对象之间共享的对象:

    public class MultiThr implements Runnable{
        private static final Object lock = new Object();
    
        public static void main(String[] args) {
            for(int i = 0;i < 5;i++){
                new Thread(new MultiThr()).start();
            }
        }
    
        @Override
        public void run() {
            increment();
        }
    
        public void increment(){
            synchronized (lock) {
                for(int i=0;i<10;i++){
                    System.out.println(i);
                    try {
                        Thread.sleep(400);
                    } catch (InterruptedException e) {}
                }
            }
        }
    }
    

    你的increment()方法是同步的。 你的问题是它是你的Runnable的一部分。 更重要的是,你的计数器变量i是一个局部变量,所以每个线程都会拥有它自己的副本,即使没有synchronized关键字也是如此。 我建议你做的是创建一个MyConter类,如:

    class MyCounter {   
    
        private int i;
    
        public MyCounter () {
            i = 0;
        }
    
        public int getCounter() {
            return i;
        }
    
        public void increment() {
            i++;
        }
    }
    

    然后将其作为参数传递给MultiThr构造函数:

    public class MultiThr implements Runnable{
    
        private MyCounter counter;
    
        public MultiThr(MyCounter counter)  {
            this.counter = counter;
        }
    
        @Override
        public void run() {  
            increment();
        }
    
        public synchronized void increment(){
            for(int i=0;i<10;i++){
                counter.increment();
                System.out.println(counter.getCounter());
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    // Do not do just e.printStackTrace()
                    Thread.currentThread().interrupt()
                }
            }
        }
    
        public static void main(String[] args) {
            for(int i = 0;i < 5;i++){
               new Thread(new MultiThr()).start();
            }
        }
    }
    

    或者您可以使用AtomicInteger而不是MyCounter,只要确保将相同的实例传递给每个线程即可。

    链接地址: http://www.djcxy.com/p/91859.html

    上一篇: Getting object lock with synchronized method

    下一篇: what is this piece of code doing