简体   繁体   English

为什么我的同步方法可以锁定不同的对象?

[英]Why can my synchronized methods lock on different objects?

I am learning Java concurrency right now. 我现在正在学习Java并发。 I came across a piece of code like this: 我遇到了一段这样的代码:

package pac1;

import java.util.*;
import java.util.concurrent.*;

class A1 {
    public void f() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("f()");
        }
    }
}

class B1 {
    public void g() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("g()");
        }
    }
}

class C1 {
    public void p() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("p()");
        }
    }

}

public class V {
    public static void main(String[] args) {
        A1 a = new A1();
        B1 b = new B1();
        C1 c = new C1();
        new Thread() {
            public void run() {
                a.f();
            }
        }.start();
        new Thread() {
            public void run() {
                c.p();
            }
        }.start();
        b.g();
    }

}

Since this code uses different objects to call synchronized methods, I supposed that it would not prevent them from interfering with each other. 由于此代码使用不同的对象来调用同步方法,因此我认为这不会阻止它们相互干扰。 However, the result is as follows: 但是,结果如下:

f()
f()
f()
f()
f()
g()
g()
g()
g()
g()
p()
p()
p()
p()
p()

BTW, the result is the same using Lock: 顺便说一句,使用Lock的结果是相同的:

package pac1;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class A {
    Lock lock = new ReentrantLock();

    public void f() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("f()");
        } finally {
            lock.unlock();
        }
    }
}

class B {
    Lock lock = new ReentrantLock();

    public void g() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("g()");
        } finally {
            lock.unlock();
        }
    }
}

class C {
    Lock lock = new ReentrantLock();

    public void p() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("p()");
        } finally {
            lock.unlock();
        }
    }
}

public class Ex16 {

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();
        new Thread() {
            public void run() {
                a.f();
            }
        }.start();
        new Thread() {
            public void run() {
                c.p();
            }
        }.start();
        b.g();
    }

}

You don't need a lock or synchronized here. 您不需要在这里锁定或同步。 Sychronized is used to lock access to shared mutable state. 同步用于锁定对共享可变状态的访问。 You don't have any shared mutable state to begin with. 首先,您没有任何共享的可变状态。

You have 3 threads here and nobody can predict the order in which those threads run because of context switching. 这里有3个线程,由于上下文切换,没有人能预测这些线程的运行顺序。 I don't see a problem. 我没问题。

Actually the loops simply are not long enough hence allowing threads to finalize in the same order they were launched. 实际上,循环还不够长,因此允许线程以与启动时相同的顺序完成。 In order to make apparent that threads do not interfere you may try one of the following approaches : 为了使线程不干扰您可以尝试以下方法之一:

  • Make the loop to run longer, eg 1000 iterations should be more then enough : 使循环运行更长的时间,例如1000次迭代就应该足够了:

    synchronized (this) { for (int i = 0; i < 1000; i++) System.out.println("f()"); }

  • Suspend the threads within the loops but make sure to have different intervals set for each loop : 挂起循环中的线程,但请确保为每个循环设置不同的间隔:

    synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println("p()"); try { Thread.sleep(3000); } catch (final InterruptedException ex) { // Swallow } } }

So long story short : These locks actually do not interfere. 长话短说:这些锁实际上并不干扰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM