多线程+缓冲池demo
来源:互联网 发布:att 4g网络频段 编辑:程序博客网 时间:2024/05/27 20:49
缓冲池的特点在于:需要把缓冲池填满后,再从缓冲池里面往外拿数据,直到拿完,然后再向缓冲池填充,然后再拿完。循环往复,直到结束。
其中,有两种写法:一种是用synchronized(java.lang.Thread)写,另一种用lock写(java.util.concurrent.locks.ReentrantLock)。
lock是synchronized的优化。简单来说,lock较synchronized的优势在于,能根据condition区分线程的类别。lock优点举例:比如著名的生产者消费者问题,一种线程是生产的,一种线程是消费的。在处理等待与唤醒线程时候,可以很简易的实现只唤醒生产类的(或消费类的)线程。而synchronized的话,因为不能分类,所以只能用notifyAll()唤醒所有,并且加上判断的逻辑代码逻辑,来实现只唤醒生产类别的(或消费类的)线程。
synchronized实现多线程+缓冲池的demo运行结果如下,先看结果便于理解,下面是demo::
Thread-0放入缓存池第:0个,值为:0.8650381718966005||count:1
Thread-1放入缓存池第:1个,值为:0.18903274362559364||count:2
Thread-1放入缓存池第:2个,值为:0.8153818753787416||count:3
Thread-1放入缓存池第:3个,值为:0.8959388103335012||count:4
Thread-1放入缓存池第:4个,值为:0.9045283673786046||count:5
————Thread-2拿出缓存池第:0个,值为:0.8650381718966005||count:4
————Thread-2拿出缓存池第:1个,值为:0.18903274362559364||count:3
————Thread-2拿出缓存池第:2个,值为:0.8153818753787416||count:2
————Thread-2拿出缓存池第:3个,值为:0.8959388103335012||count:1
————Thread-2拿出缓存池第:4个,值为:0.9045283673786046||count:0
Thread-0放入缓存池第:0个,值为:0.2860196523337297||count:1
Thread-1放入缓存池第:1个,值为:0.6776095429604442||count:2
Thread-0放入缓存池第:2个,值为:0.7962449560468262||count:3
Thread-0放入缓存池第:3个,值为:0.3371961229706687||count:4
Thread-0放入缓存池第:4个,值为:0.2703163622926409||count:5
————Thread-3拿出缓存池第:0个,值为:0.2860196523337297||count:4
————Thread-3拿出缓存池第:1个,值为:0.6776095429604442||count:3
————Thread-3拿出缓存池第:2个,值为:0.7962449560468262||count:2
————Thread-3拿出缓存池第:3个,值为:0.3371961229706687||count:1
————Thread-3拿出缓存池第:4个,值为:0.2703163622926409||count:0
……
synchronized实现多线程+缓冲池的demo如下::
package com.zyf.test.bufferpool;public class BufferPoolTest { public static void main(String[] args) { BufferPool bp = new BufferPool(); PutBufferObj put = new PutBufferObj(bp); TakeBufferObj take = new TakeBufferObj(bp); Thread t1 = new Thread(put); Thread t2 = new Thread(put); Thread t3 = new Thread(take); Thread t4 = new Thread(take); t1.start(); t2.start(); t3.start(); t4.start(); }}class BufferPool{ private int putNum = 0; private int takeNum = 0; private int count = 0; private Object[] objs = new Object[5]; private boolean flag = false; public void putObj(Object obj) throws InterruptedException{ synchronized(this){ while(flag == true) this.wait(); //当该放入缓存池最后一个obj时 if(putNum == objs.length-1){ objs[putNum] = obj; System.out.println(Thread.currentThread().getName()+"放入缓存池第:"+putNum+"个,值为:"+obj.toString()+"||count:" +(count+1)); putNum = 0; flag = true;//当缓存池放满后,通过设置flag,使放入的操作wait }else{ objs[putNum++] = obj; System.out.println(Thread.currentThread().getName()+"放入缓存池第:"+(putNum-1)+"个,值为:"+obj.toString()+"||count:" +(count+1)); } count++; this.notifyAll(); } } public Object TakeObj() throws InterruptedException{ synchronized(this){ while(flag == false) this.wait(); Object obj; //当该拿出缓存池最后一个obj时 if(takeNum == objs.length-1){ obj = objs[takeNum]; System.out.println("------------"+Thread.currentThread().getName()+"拿出缓存池第:"+takeNum+"个,值为:"+obj.toString()+"||count:" +(count-1)); takeNum = 0; flag = false;//当缓存池拿空后,使拿出的操作wait }else{ obj = objs[takeNum++]; System.out.println("------------"+Thread.currentThread().getName()+"拿出缓存池第:"+(takeNum-1)+"个,值为:"+obj.toString()+"||count:" +(count-1)); } count--; this.notifyAll(); return obj; } }}class PutBufferObj implements Runnable{ private BufferPool bufferPool; PutBufferObj(BufferPool bufferPool){ this.bufferPool = bufferPool; } @Override public void run(){ boolean flag = true; while(true){ try { bufferPool.putObj(Math.random()); flag = !flag; } catch (InterruptedException e) { e.printStackTrace(); } } }}class TakeBufferObj implements Runnable{ private BufferPool bufferPool; TakeBufferObj(BufferPool bufferPool){ this.bufferPool = bufferPool; } @Override public void run() { while(true){ try { bufferPool.TakeObj(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
用lock的话,就更为简单,例子如下:
package com.zyf.test.bufferpool;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class BufferPoolLockTest { public static void main(String[] args) { BufferPoolLock bp = new BufferPoolLock(); PutBuf pb = new PutBuf(bp); TakeBuf tb = new TakeBuf(bp); Thread t1 = new Thread(pb); Thread t2 = new Thread(pb); Thread t3 = new Thread(tb); Thread t4 = new Thread(tb); t1.start(); t2.start(); t3.start(); t4.start(); }}class BufferPoolLock{ private int putNum,takeNum,count; private Object[] objs = new Object[5]; Lock lock = new ReentrantLock(); Condition notnull = lock.newCondition(); Condition notfull = lock.newCondition(); public void put(Object obj) throws InterruptedException{ lock.lock(); try{ while(count == objs.length) notfull.await(); objs[putNum++] = obj; System.out.println(Thread.currentThread().getName() +"在缓冲池放入了"+obj.toString() +"在:"+(putNum-1)+"位置,放入后count:"+(count+1)); if(putNum == objs.length) putNum = 0; count++; notnull.signal(); }finally{ lock.unlock(); } } public Object take() throws InterruptedException{ lock.lock(); try{ while(count == 0) notnull.await(); Object obj = objs[takeNum++]; System.out.println(Thread.currentThread().getName() +"-----------------------在缓冲池拿出了"+obj.toString()+"__" +(putNum-1)+"位置的数据,拿出后count:"+(count-1)); if(takeNum == objs.length) takeNum = 0; count--; notfull.signal(); return obj; }finally{ lock.unlock(); } }}class PutBuf implements Runnable{ private BufferPoolLock bp; PutBuf(BufferPoolLock bp){ this.bp = bp; } public void run(){ while(true) try { bp.put(Math.random()); } catch (InterruptedException e) { e.printStackTrace(); } }}class TakeBuf implements Runnable{ private BufferPoolLock bp; TakeBuf(BufferPoolLock bp){ this.bp = bp; } public void run(){ while(true) try { bp.take(); } catch (InterruptedException e) { e.printStackTrace(); } }}
- 多线程+缓冲池demo
- 多线程阻塞队列缓冲池
- 环缓冲demo
- SurfaceView双缓冲Demo
- SurfaceView双缓冲Demo
- 线程池,多线程使用方法,demo
- 多线程Demo
- 多线程demo
- 【多线程】一个简单的线程池Demo
- Ringbuffer在实时流缓冲的demo
- 缓冲池
- 缓冲池
- JAVA多线程demo
- android handler 多线程demo
- 多线程学习Demo
- android handler 多线程demo
- android handler 多线程demo
- 多线程两个小demo
- 五十道编程小题目 --- 04 正整数分解质因数 java
- 幻方
- BZOJ2091——[Poi2010]The Minima Game
- 计算机中如何表示数字-07IEEE754浮点数标准
- 【探索】Get与Post
- 多线程+缓冲池demo
- Cpp_Primer--运算符
- 【hihocoder1082】然而沼跃鱼早就看穿了一切——字符串
- 数据链路层协议
- oracle row_number函数操作(含实例)
- 【IOS学习】网络请求中的cookie
- PAT乙级.1024. 科学计数法 (20)
- 简单封装Google的二维码生成/解析工具——zxing
- phabricator/github版本提交前公钥秘钥的设置与版本合并问题