多线程+缓冲池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();            }    }}
0 0
原创粉丝点击