【问题标题】:using this keyword with synchronized block in java在java中使用这个关键字和同步块
【发布时间】:2018-09-02 13:10:58
【问题描述】:

我有两个线程可以访问一个对象。使用同步(a),我在对象a上提供锁,所以现在每次线程都可以访问对象“a”并修改它。如果执行此代码,我们有1 2。有时没有同步块我们得到2 2。(线程 t1 获得 i 并增加 i 现在线程 t2 获得 i 并增加线程 t1 获得 i 并打印 2,线程 t2 获得 i 并打印 2) 如果我是真的,为什么我们不能使用 synchronized(this) 而不是 synchronized(a)?

public class Foo {

    public static void main(String[] args) {
        B b =new B();
        b.start();

    }

}
class B{

    A a = new A();
    Thread t1 =new Thread(new Runnable(){
        public void run(){
            synchronized(a){

                a.increment();

            }
        }
    });
    Thread t2 =new Thread(new Runnable(){
        public void run(){
            synchronized(a){

                a.increment();

            }
        }
    });
    public void start(){
        t1.start();
        t2.start();
    }

}
class A{
    int i = 0;
    public void increment() {
        i++;
        System.out.println(i);
    }
}

【问题讨论】:

    标签: java multithreading synchronized-block


    【解决方案1】:

    如果我是真的,为什么我们不能使用 synchronized(this) 而不是 synchronized(a)?

    如果你这样做了:

    public void run() {
        synchronized (this) {
            a.increment();
        }
    }
    

    在这种情况下,this 是封闭类实例,这里是匿名 Runnable 对象,并且由于每个线程都有自己的 Runnable 实例,因此您的同步是在单独的对象上进行的,并且不会起作用。您必须在 B.this 上进行同步才能使其正常工作。

    public void run() {
        synchronized (B.this) {
            a.increment();
        }
    }
    

    或任何其他对所有同步块都相同的唯一对象。

    或者如果你想使用synchronized (this),那么使用一个Runnable:

    class B {
        A a = new A();
    
        Runnable r = new Runnable() {
            public void run() {
                synchronized (this) {
                    a.increment();
                }
            };
        };
    
        public void start() {
            // t1.start();
            // t2.start();
    
            new Thread(r).start();
            new Thread(r).start();
        }
    }
    

    【讨论】:

    • 哇,有人在我进行更改时评论了我的更改。伟大的思想都一样!
    【解决方案2】:

    另一种方法:

    使方法increment同步

    public class Foo {
    
        public static void main(String[] args) {
            new B().start();
        }
    }
    
    class B {
    
        A       a   = new A();
        Thread  t1  = new Thread(new Runnable() {
    
                        @Override
                        public void run() {
                            a.increment();
                        }
                    });
        Thread  t2  = new Thread(new Runnable() {
    
                        @Override
                        public void run() {
                            a.increment();
                        }
                    });
    
        public void start() {
            t1.start();
            t2.start();
        }
    }
    
    class A {
    
        int i = 0;
    
        public synchronized void increment() {   // <<<<<<<<
            i++;
            System.out.println(i);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-19
      • 2012-12-09
      • 1970-01-01
      • 2012-03-01
      • 2011-12-10
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多