【发布时间】:2019-08-14 18:54:48
【问题描述】:
我了解到线程可以锁定“资源”,比如说一个对象,它们正在使用,因此一次只允许使用和修改一个对象,这就是同步问题。我创建了一个类的两个不同实例并将其提供给我的线程,试图确保它们锁定不同的“资源”。他们如何仍然表现得好像他们已经锁定了相同的资源?我很困惑,因为我对线程没有任何经验和知识。
所以这是我从在线教程修改的代码,以尝试我的想法:
public class TestThread {
public static void main(String args[]) {
PrintDemo PD1 = new PrintDemo("No.1"); //just prints from 1 to 5
PrintDemo PD2 = new PrintDemo("No.2");
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD1 );
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD2 );
T1.start();
T2.start();
// wait for threads to end
try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemo PD;
ThreadDemo( String name, PrintDemo pd) {
threadName = name;
PD = pd;
}
public void run() {
synchronized(PD) {
PD.printCount();
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
class PrintDemo {
private String name;
PrintDemo(String name) {
this.name = name;
}
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + " Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
每次跑步应该都不一样,但总是一样的:
输出:
开始线程 - 1 开始线程 - 2 1号柜台--- 5 1号柜台---4 1号柜台--- 3 1号柜台---2 1号计数器--- 1 线程 线程 - 1 退出。 2号柜台--- 5 2号柜台--- 4 2号柜台--- 3 2号柜台--- 2 2号柜台--- 1 线程 线程 - 2 退出。编辑#1:我按照你的要求放置了整个代码。我还测试了代码而不覆盖开始。结果是一样的。
【问题讨论】:
-
您多久运行一次代码?两次相同的输出是很有可能的,2000 次仍然是可能的,但不太可能。也许不要打印 5 次而是 1000 次,以便让线程有更多时间发散。
-
为什么要覆盖
start()方法?...藏在那里的是什么?覆盖start()是非常不寻常的。 -
不要扩展
Thread,而是实现Runnable。您可能通过覆盖Thread.start()导致了问题,这会阻止Thread在单独的线程中实际运行。不要这样做。 -
P.S.,这两个线程打印的行的交错应该每次都不同。只是它可能有所不同。我知道第一个线程总是在第二个线程开始之前运行完成有点可疑,但仅此而已 - 可疑 - 它并不能证明您的 Java 运行时或操作系统有任何问题。
-
@SolomonSlow 我编辑了这篇文章,所以你可以看到它是什么。我也尝试过没有覆盖开始。结果相同
标签: java multithreading thread-synchronization