同步线程方法正在并发执行 - 为什么?
我有一个关于线程的问题。我有以下Thread类并创建2个线程对象。同步线程方法正在并发执行 - 为什么?
public class MyThread extends Thread{
String name="";
public MyThread(String string) {
name=string;
}
@Override
public void run() {
callMe();
}
synchronized private void callMe() {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
a.start();
b.start();
}
}
当我执行此,输出我得到的是 -
Started
Started
B = 1
B = 2
A = 1
A = 2
B = 3
A = 3
B = 4
A = 4
B = 5
A = 5
我知道,当线程调度捡起来,A和B是随机打印。
但我的问题是:为什么循环不是一个接一个地执行?我已使用关键字。
你方法是有效的:
private void callMe() {
synchronized(this) {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
现在你已经创建了两个不同的实例,所以this
会为每个线程的不同...所以他们不同步相互对抗。如果你想看到两个线程与相同监测工作,你可以重写你的代码是这样的:
public final class DemoRunnable implements Runnable {
@Override
public synchronized void run() {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " = " + i);
}
}
public static void main(String[] args) {
Runnable runnable = new DemoRunnable();
Thread a = new Thread(runnable, "A");
Thread b = new Thread(runnable, "B");
a.start();
b.start();
}
}
然后你会得到的输出是这样的:
Started
A = 1
A = 2
A = 3
A = 4
A = 5
Started
B = 1
B = 2
B = 3
B = 4
B = 5
(虽然它可以)
我们仍然有两个线程,但他们在同一个对象上调用同步方法(在这种情况下为DemoRunnable
),所以必须等待另一个线程完成。
的几点:
- 实施
Runnable
通常优于延伸Thread
;它更灵活 - 在
Thread
对象上同步有其自身的问题,因为Thread
类自己做;尽量避免它 - 我个人不喜欢
this
同步反正 - 我通常会对Object
类型的私人最终变量来表示只有我的代码知道...这样,我可以很容易地看到显示器所有,可以在其上同步的代码,这使得它更容易推理
为每个对象同步的作品。要跨实例进行同步,您需要共享对象才能进行同步。
I.e.
private final static Object globalLock = new Object();
// Later
private void callMe() {
synchronized (globalLock) {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
因为2个线程正在通过2个不同的对象执行。
好吧,您现在必须从其他答案中实现。您正在创建2个独立的对象,即。 a和b。现在,当您调用start方法时,将启动一个新线程,通过相应(单独不相同)对象的run方法执行。同步确实在该方法上,但恰好有一个线程通过a的callMe方法运行,恰好有一个线程通过b的callMe方法运行。所以,你的期望输出应该是:
A - 1 A - 2 A - 3 ...
没有发生。
希望这有助于
-1 - 这是一个非常简洁的答案。没有足够的信息来解释问题发生的原因。 – 2014-10-08 11:02:36
好的,好吧,我会详细说明:) – Ironluca 2014-10-08 11:04:18
代码等于本守则
private void callMe(){
synchronized(this){
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
您只需S与当前对象同步。 如果你想将它们彼此同步您的需要同步到类, 这样的:
private void callMe(){
synchronized(MyThread.class){
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
因此,在你的第一个代码片段中,它不会保持Synchronized'method'正确吗?它变成Synchronized'语句'。第二个代码片段就是Synchronized'method'的一个例子,对吗? – 2014-10-08 11:36:52
@NinadPingale:是的,但这种差异实际上是不相关的 - “同步”方法实际上是一个包含方法体的'synchronized(this)'语句的普通方法。 (例如方法;对于静态方法,它在'Class'对象上同步。) – 2014-10-08 11:38:16