package wait;
import java.util.concurrent.TimeUnit;
/**
* 启动两个线程,这两个线程能够交换数据
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
final Test t = new Test();
new Thread(new Runnable() {
public void run() {
t.await();
}
}).start();
TimeUnit.MILLISECONDS.sleep(100);
new Thread(new Runnable() {
public void run() {
t.asingle("12");
}
}).start();
}
String s = null;
boolean f = false;
//等待端,等待接受数据
synchronized void await() {//process首先等待,直到connector把f变成true
while (!f) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
f = false;
System.out.println(Thread.currentThread() + ",await,s:" + s);
notifyAll();
System.out.println("ok");
}
//发送端,
synchronized void asingle(String str) {//connector不会等待;但是后面的
while (f) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.s = str;//存储s,线程交换数据
f = true;
notifyAll();
System.out.println(Thread.currentThread() + ",asingle");
}
}
package wait;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.TimeUnit;
/**
* 除了上面那种方法外,java.io包也提供了另外的方法来完成类似的事情
* 管道流,线程间通信的管道用来交换数据的。使用的是生产者消费者模式
*
* 网上比较流行的是弄一个容器,然后读写同步
*/
public class PipeTest {
public static void main(String[] args) throws InterruptedException {
final PipedInputStream in = new PipedInputStream(3);//消费者
final PipedOutputStream out = new PipedOutputStream();//生产者
new Thread(new Runnable() {
public void run() {
try {
//消费者链接生产者,并且能够读取生产者生产的数据;这不是网络链接,这紧紧是一种伪连接
in.connect(out);
int n = -1;
while ((n = in.read()) != -1) {
System.out.println(Thread.currentThread() + ",r:" + n);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
//假延迟,等待消费者线程启动完毕并且执行了connect,如果消费者没有在那里等待,那么生产者写数据会抛出异常
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
for (int i = 0; i < 20000; i++) {
out.write(i);//生产数据
System.out.println(Thread.currentThread() + ",w:" + i);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}