我写了一个示例程序来说明使用管道是线程。我创建了2个帖子。
Thread1正在发送“Hi this is thread1”并调用wait()以完成第2个线程。
Thread2正在打印thread1发送的消息,并且还会附加到字符串缓冲区中,然后一旦收到整个消息,thread2将打印字符串缓冲区的内容并调用notify。现在调用wait()并通知两个线程往往处于死锁状态
奇怪的是,thread2打印了一条消息但没有打印字符串缓冲区的内容。
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
synchronized (obj)
{
obj.wait();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
OUTPUT :: 你好,我是thread1
更新了决议:
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj)
{
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
现在我有点困惑了。我刚从try catch到最后移动了wait()。它是如何影响Pipestream阻塞的?
答案 0 :(得分:2)
问题在于
data = pipeinputstream.read();
线程2中的是阻塞调用。来自PipedInputStream#read()
此方法阻塞,直到输入数据可用,结束 检测到流,或抛出异常。
线程2一直等待,直到其中一件事发生。由于它们都不会发生,因此线程将无法notify
另一个。
这不是死锁。
请注意,即使该调用未阻塞并返回-1,在线程1调用notify
之前,线程2仍然可以执行其wait
。在这种情况下,线程1将处于一个恒定的等待状态,你的程序将不会终止。