如何在java中使用synchronized方法实现线程的同步?
我无法在这里实现线程的同步。我用了一种同步的方法“冰毒”她。所以根据定义,一次只能有一个线程进入并打印我想要的输出。但这并没有发生。我需要帮助。多谢各位
class ABC {
synchronized public void meth(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " Thread Interrupted");
}
System.out.println("]");
}
}
class SyncMethod implements Runnable {
ABC a = new ABC();
Thread t;
SyncMethod(String s) {
t = new Thread(this, s);
t.start();
}
public void run() {
a.meth(t.getName());
}
public static void main(String args[]) {
new SyncMethod("Hello");
new SyncMethod("Synchronized");
new SyncMethod("World");
}
}
电流输出:
[Hello [Synchronized [World] ] ] ]
期望输出:
[Hello]
[Synchronized]
[World]
# 1 楼答案
看这里,每次调用SyncMethod的构造函数时,您都在创建ABC的新实例,因此您有3个由不同线程调用的类的副本,这样它们就不会竞争监视器,所以您需要的是在所有3个调用中使用相同的ABC对象。这里是解决方案
}
# 2 楼答案
在实例方法上同步时:
这与:
也就是说,您正在获取的监视器是该类的实例。但是您要创建3个单独的实例(每个线程调用^{),并分别获取每个实例上的监视器,因此同步实际上是不可操作的
您需要在一个公共对象上同步。例如:
不过,一般来说,在类上进行同步是不明智的,因为程序中任何地方的任何代码都可以获取该监视器,因此您可能会遇到意外的争用
而是传入一个锁对象:
并将相同的
lock
传递给所有要同步的ABC
实例但是,不必像urag points out in his/her answer那样做,您可以将
ABC
的同一个实例传递给所有线程,而不是在每个SyncMethod
中创建一个新实例。有时候,当我在写答案时,最简单的解决方案就从我的脑海中消失了;)# 3 楼答案
我自己提出了一个更好的解决方案。正如@urag所说,我们需要一个对象来调用同步方法,而我在evrytime创建一个新对象,因此调用了3个同步方法。我们可以使ABC类的对象成为静态的,因此它不会自我更新,代码也会变得更短。我已经检查过了