我有一个关于线程的问题。我有以下 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 是在线程调度程序选择时随机打印的。
但我的问题是:为什么循环没有一个接一个地执行?我使用了 synchronized
关键字。
最佳答案
你的 synchronized
方法是有效的:
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
类(class)自己做;尽量避免它 - 我个人不喜欢在
this
上同步无论如何——我通常会有一个类型为Object
的 private final 变量。表示只有我的代码知道的监视器...这样我就可以很容易地看到所有可以在它上面同步的代码,这使得推理更容易
关于java - 同步线程方法并发执行 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255221/