我有一个典型的问题:“我的代码可以运行,但我不知道为什么”。
我有一个程序创建了一个线程,当我从扫描器接收到特定输入时,我将字符串的控制权传递给工作线程。为此,我使我的线程wait(),当我从UI线程获得正确的输入时,我会notify()。
以下是我的代码。为简单起见,我只使用了一个线程。
package main;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
volatile Boolean keepRunning = true;
private Queue<String> q = new LinkedList<String>();
ThreadDemo( String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void in(String ex){
q.add(ex);
System.out.println("Added " + ex + "to queue of " + threadName);
synchronized(t){
t.notify();
}
}
public void run() {
System.out.println("Starting to loop.");
while (keepRunning) {
try {
//Why does it matter that I synchronized t?
synchronized(t){
System.out.println(threadName + "Waiting");
t.wait();
}
} catch (InterruptedException e) {
System.out.println("Thread interrupted " + e.toString());
}
System.out.println(threadName + "notified");
if (q.size()>0){
String out = q.remove();
System.out.println(threadName + "received " + out);
}
}
System.out.println("Done looping.");
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
public class DataAnalysisProgram {
public static void main(String[] args) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
System.out.println("say something");
Scanner s = new Scanner(System.in);
String t;
do{
t = s.next();
T1.in(t);
}while (!t.equals("stop"));
T1.keepRunning = false;
T1.interrupt();
s.close();
}
}
这个代码可以正常工作。我的线程会等待直到我使用notify。然而,我并不真正理解我调用notify和wait的对象的重要性。
在我的实现中,我随意使用了t.wait()/t.notify(),其中t是我的线程对象。如果我使用threadName.wait()/threadName.notify(),它也应该能工作。为什么我们要在看似随意的对象上调用notify和wait呢?我知道我在notify和wait方面缺少一些概念。