多线程之线程通信摘要
2018-01-07 19:46
267 查看
首先我们要知道进程之间的通讯方式有哪些?
#管道( pipe ) #消息队列(
message queue ) #共享内存(
shared memory ) :#套接字(
socket ) 等等--
线程的通讯方式:
1 wait/notify 机制
wait()方法和notify()方法是Object类提供的方法,而在使用的条件就是当前线程必须有自己的监听器
否则就是抛出异常,我们可以使用jvm提供的内置锁 synchronized 关键字来配合使用;注意如果有多个
线程等待,当某一线程发起唤醒操作,会随机唤醒一个线程,而非所有线程,如果想唤醒所有线程,可以使用
notifyAll()方法
下面是 启动一个等待线程和一个通知线程的例子
先启动一个等待线程,然后启动唤醒线程
测试结果如下:
wait start time = 1515326744453
notify start time = 1515326747453
notify end time = 1515326747453
wait end time = 1515326747453
这样两线程之间就完成了通信,代码的关键是注册了同一把锁,在这个对象锁中我们可以理解有两种队列,即 等待队列和就绪队列,对象调用wait方法,则标记线程信息进入等待队列并释放锁,调用notify方法则 队列中的线程进入就绪队列竞争获取锁,这种方式其实可以理解为是内存共享
2生产者/消费者模式
比如常用的消息队列bolckingqueue都是基于生产者消费者模型实现的。其本质上是基于wait/notify机制实现的
例如我们通过wait/notify的方式实现这种模式
结果是:会不停读取生存者线程中的数据,并把它变成空字符串
这是1对1的生产者消费者模型简单实现
3 管道
java中有提供管道流这种api ,重点是四个类
PipedInputStream
PipedOutputStream
PipedWriter
PipedRead
上述四个类可用于管道字节流和字符流的实现,
我们通过字符流的方式 实现线程之间的通信
如下
结果如下
write :
write data = 012345678910111213141516171819
read :
result data = 012345678910111213141516171819
线程之间完成了通信
其他线程通信方式比如 java socket方式等也可以实现,这里不再叙述
知识点来源: java多线程编程核心技术
#管道( pipe ) #消息队列(
message queue ) #共享内存(
shared memory ) :#套接字(
socket ) 等等--
线程的通讯方式:
1 wait/notify 机制
wait()方法和notify()方法是Object类提供的方法,而在使用的条件就是当前线程必须有自己的监听器
否则就是抛出异常,我们可以使用jvm提供的内置锁 synchronized 关键字来配合使用;注意如果有多个
线程等待,当某一线程发起唤醒操作,会随机唤醒一个线程,而非所有线程,如果想唤醒所有线程,可以使用
notifyAll()方法
下面是 启动一个等待线程和一个通知线程的例子
public class MyThread1 extends Thread { private Object lock; public MyThread1(Object lock) { this.lock = lock; } @Override public void run() { try { synchronized (lock) { System.out.println("wait start time = " + System.currentTimeMillis()); lock.wait(); System.out.println("wait end time = " + System.currentTimeMillis()); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class MyThread2 extends Thread { private Object lock; public MyThread2(Object lock) { this.lock = lock; } @Override public void run() { try { synchronized (lock) { System.out.println("notify start time = " + System.currentTimeMillis()); lock.notify(); System.out.println("notify end time = " + System.currentTimeMillis()); } } catch (Exception e) { e.printStackTrace(); } } }
public class Test1 { public static void main(String[] args) throws Exception { Object lock = new Object(); MyThread1 thread1 = new MyThread1(lock); thread1.start(); TimeUnit.SECONDS.sleep(3); MyThread2 thread2 = new MyThread2(lock); thread2.start();
先启动一个等待线程,然后启动唤醒线程
测试结果如下:
wait start time = 1515326744453
notify start time = 1515326747453
notify end time = 1515326747453
wait end time = 1515326747453
这样两线程之间就完成了通信,代码的关键是注册了同一把锁,在这个对象锁中我们可以理解有两种队列,即 等待队列和就绪队列,对象调用wait方法,则标记线程信息进入等待队列并释放锁,调用notify方法则 队列中的线程进入就绪队列竞争获取锁,这种方式其实可以理解为是内存共享
2生产者/消费者模式
比如常用的消息队列bolckingqueue都是基于生产者消费者模型实现的。其本质上是基于wait/notify机制实现的
例如我们通过wait/notify的方式实现这种模式
public class P { private Object lock; P(Object lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObject.value.equals("")) { lock.wait(); } String value = System.currentTimeMillis() + "_" + System.nanoTime(); System.out.println("set value = " + value); ValueObject.value = value; lock.notify(); System.out.println("p notify"); } } catch (Exception e) { e.printStackTrace(); } } }
public class C { private Object lock; C(Object lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObject.value.equals("")) { lock.wait(); } System.out.println("get value = " + ValueObject.value); ValueObject.value = ""; lock.notify(); System.out.println("c notify"); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class ThreadP extends Thread { private P p; public ThreadP(P p) { this.p = p; } @Override public void run() { while (true) { p.setValue(); } } }
public class ThreadC extends Thread { private C c; public ThreadC(C c) { this.c = c; } @Override public void run() { while (true){ c.getValue(); } } }
public class ValueObject { public static String value = ""; }
public class Test { public static void main(String[] args) { String lock = new String(""); P p = new P(lock); C c = new C(lock); ThreadP threadP = new ThreadP(p); ThreadC threadC = new ThreadC(c); threadP.start(); threadC.start(); }
结果是:会不停读取生存者线程中的数据,并把它变成空字符串
这是1对1的生产者消费者模型简单实现
3 管道
java中有提供管道流这种api ,重点是四个类
PipedInputStream
PipedOutputStream
PipedWriter
PipedRead
上述四个类可用于管道字节流和字符流的实现,
我们通过字符流的方式 实现线程之间的通信
如下
public class WriteData { public void writeMethod(PipedWriter writer) { try { StringBuilder data = new StringBuilder(); System.out.println("write : " ); for (int i = 0; i < 20; i++) { data.append(i); writer.write("" + i); } System.out.println("write data = " + data); } catch (Exception e) { e.printStackTrace(); } } }
public class ReadData { public void readMethod(PipedReader reader) { StringBuilder d = new StringBuilder(); try { System.out.println("read : "); char[] buffer = new char[5]; int readLength; while ((readLength = reader. 4000 read(buffer)) !=-1) { String data = new String(buffer, 0 ,readLength); d.append(data); } reader.close(); } catch (Exception e) { }finally { System.out.println("result data = " + d); } } } public class R
public class Run { public static void main(String[] args) throws Exception { WriteData writeData = new WriteData(); ReadData readData = new ReadData(); PipedReader reader = new PipedReader(); PipedWriter writer = new PipedWriter(); // reader.connect(writer); writer.connect(reader); new Thread(() -> writeData.writeMethod(writer)).start(); TimeUnit.SECONDS.sleep(2); new Thread(() -> readData.readMethod(reader)).start(); } }
结果如下
write :
write data = 012345678910111213141516171819
read :
result data = 012345678910111213141516171819
线程之间完成了通信
其他线程通信方式比如 java socket方式等也可以实现,这里不再叙述
知识点来源: java多线程编程核心技术
相关文章推荐
- Java 多线程编程之六:线程之间的通信(附源代码)
- 多线程的使用及线程的通信
- 多线程学习07-线程间通信
- Java 多线程(七) 线程间的通信——wait及notify方法
- Java 多线程之线程间的通信——wait及notify方法
- 多线程之7 -------线程锁与通信
- Java 多线程(七) 线程间的通信——wait及notify方法
- 线程状态,多线程的使用,线程的通信(总结)
- Java基础视频教程第12天_多线程二之线程间通信
- 多线程一共就俩问题:1.线程安全(访问共享数据) 2.线程通信(wait(),notify())
- 大话Android多线程(三) 线程间的通信机制之Handler
- 多线程并发之线程间的通信,notify,wait
- (48)Java学习笔记——多线程 / 线程间通信 / 线程组 / 线程池 /
- 多线程专题之线程间的通信
- java多线程-线程间通信_代码优化
- Java多线程四:线程间通信/等待唤醒机制
- 多线程系列六-线程间通信 wait和notify、threadlocal等
- 多线程之线程通信条件Condition二
- 线程--简单多线程通信实例
- Java 多线程编程之六:线程之间的通信(附源代码)