线程间通信,顾名思义,就是指线程之间的联系和交互。线程间通信在多线程中有着广泛的运用,大大便利了多线程之间的同步和交互。本文我们就来探讨如何实现线程间通信。
一般情况下,多线程之间实现线程间通信有4种方式:
1. 共享变量
线程之间通过共享一个对象,在同步块中访问该对象中数据来实现通信。
下面是一个例子,创建了两个线程thread1和thread2,创建了Runnable实现类对象task,thread1和thread2共享task对象,在synchronized同步块中访问count数据,实现两个线程间的通信。
public class Main5 implements Runnable {
public Integer count=0;
public void run(){
int temp;
synchronized(this){
count++;
temp=count;
}
System.out.println(Thread.currentThread().getName()+" count: "+temp);
}
public static void main(String args[]){
Main5 task=new Main5();
Thread thread1=new Thread(task,"thread1");
Thread thread2=new Thread(task,"thread2");
thread1.start();
thread2.start();
}
}
2.使用Object类方法wait(),notify(),notifyAll()
线程执行wait()后,就放弃了运行资格,处于冻结状态;线程运行时,内存中会建立一个线程池,冻结状态的线程都存在于线程池中,notify()执行时唤醒的也是线程池中的线程,线程池中有多个线程时唤醒第一个被冻结的线程。
notifyall(), 唤醒线程池中所有线程。
wait(), notify(),notifyall()都用在同步里面,因为这3个函数是对持有锁的线程进行操作,而只有同步才有锁,所以要使用在同步中。
wait(),notify(),notifyall(), 在使用时必须标识它们所操作的线程持有的锁,因为等待和唤醒必须是同一锁下的线程;而锁可以是任意对象,所以这3个方法都是Object类中的方法。
3. Lock/Condition机制
如果程序不采用synchronized关键字进行同步控制,而是采用Lock对象进行同步控制,那么程序就不能使用隐式的同步监控对象,因而也就不能使用wait(), notify(), notifyAll方法来协调线程的运行。
当使用Lock对象进行同步时,Java提供Condition类来协调线程的运行。
4.管道
管道流是Java线程常用的通信方式,该通信机制的主要流程如下:
1)创建管道输出流PipedOutputStream pos和管道输入流PipedInputStream pis;
2)将管道输出流连接到管道输入流;
2)将管道输出流赋给写信息的线程,将管道输入流赋给接收信息的线程;
示例程序如下:
//写线程
import java.io.PipedOutputStream;
public class OutIO extends Thread{
private PipedOutputStream pos;
public OutIO(PipedOutputStream pos){
this.pos=pos;
}
public void run(){
String s="hello,world";
try{
pos.write(s.getBytes());
}catch(Exception e){
e.printStackTrace();
}
System.out.println("write the words: "+s);
}
}
//读线程
import java.io.PipedInputStream;
public class InIo extends Thread{
private PipedInputStream pis;
public InIo(PipedInputStream pis){
this.pis=pis;
}
public void run(){
byte[] bytes=new byte[20];
try{
pis.read(bytes,0,20);
String temp=new String(bytes);
temp=temp.trim();
System.out.println("get the words: "+temp);
}catch(Exception e){
e.printStackTrace();
}
}
}
//主程序
import java.io.PipedOutputStream;
import java.io.PipedInputStream;
public class Main8 {
public static void main(String args[]){
PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream();
try{
pos.connect(pis);
}catch(Exception e){
e.printStackTrace();
}
OutIO outIO=new OutIO(pos);
InIo inIO=new InIo(pis);
outIO.start();
inIO.start();
}
}
管道流只能在两个线程之间进行传递数据。
以上就是实现线程间通信的4种方式,其中运用比较多的是第二种通过系统方法wait()、notify()和notifyAll()实现。这一实现线程间通信的方式在本站的多线程教程中的实例有很好的体现,感兴趣的小伙伴可以去观看学习。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习