方法一:共享变量
具体:将多线程之间准备通信的变量定义为自定义线程类的成员变量
CODE1
<span style="font-size:14px;">public class Test {
public static void main(String[] args) {
MyThread t1 = new MyThread();
new Thread(t1).start();
MyThread t2 = new MyThread();
new Thread(t2).start();
MyThread t3 = new MyThread();
new Thread(t3).start();
}
}
class MyThread implements Runnable{
public int count = 0;
public synchronized void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " count is " + count++);
}
}
Console
Thread-1 count is 0
Thread-0 count is 0
Thread-2 count is 0</span>
错误1
Console 中的结果是一起出现的,而不是1S接着1S出现的,也就是说没有实现run() 方法的锁。
原因
实现 Runnable 接口的自定义线程类在创建多线程时,只需要创建一个自定义线程类实例即可,每增加一个线程,就创建一个 Thread 类即可。
上例中创建了3个 MyThread 类,也就创建了3个锁,当然不会实现同步。
错误2
count 的值并没有改变,即进程间没有实现通信。
原因
线程对象通过 synchronized 获得锁后可以单独访问 run()。但是,如果线程对象不通过 wait() 释放锁,那么其他线程对象永远无法访问 run()。
CODE2
<span style="font-size:14px;">public class Test {
public static void main(String[] args) {
Thread t0 = new Thread(myThread);
Thread t1 = new Thread(myThread);
Thread t2 = new Thread(myThread);
Thread t3 = new Thread(myThread);
Thread t4 = new Thread(myThread);
Thread t5 = new Thread(myThread);
t0.start();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class MyThread implements Runnable{
public int count = 0;
public synchronized void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " count is " + count++);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Console
Thread-0 count is 0
Thread-4 count is 1
Thread-5 count is 2
Thread-3 count is 3
Thread-2 count is 4
Thread-1 count is 5</span>
Console 中1S出现1行输出语句,说明 run() 的同步实现了,可以保证线程安全。
count 的值一直在自增,说明线程间的通信实现了。
方法二:管道流
<span style="font-size:14px;">public class Test {
public static void main(String[] args) {
// 创建管道输出流
PipedOutputStream pos = new PipedOutputStream();
// 创建管道输入流
PipedInputStream pis = new PipedInputStream();
try {
// 连接管道
pos.connect(pis);
} catch (IOException e) {
e.printStackTrace();
}
// 创建写线程
Writer w = new Writer(pos);
// 创建读线程
Reader r = new Reader(pis);
// 启动线程
w.start();
r.start();
}
}
class Writer extends Thread{
private PipedOutputStream pos;
public Writer (PipedOutputStream pos){
this.pos = pos;
}
public void run(){
try{
pos.write("Hello Customer, I am Producer.".getBytes());
pos.flush();
} catch(IOException e){
e.printStackTrace();
} finally{
try{
if(pos != null)
pos.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
class Reader extends Thread {
private PipedInputStream pis;
public Reader (PipedInputStream pis){
this.pis = pis;
}
public void run(){
byte[] buf = new byte[1024];
try{
pis.read(buf);
System.out.println(new String(buf));
} catch(IOException e){
e.printStackTrace();
} finally{
try{
if(pis != null)
pis.close();
} catch(IOException e){
e.printStackTrace();
}
}
}
}
Console
Hello Customer, I am Producer.</span>