使用优先队列PriorityBlockingQueue进行消息调度

来源:互联网 发布:再也没有 知乎 编辑:程序博客网 时间:2024/06/06 09:20
import java.util.concurrent.*;import java.util.concurrent.atomic.AtomicBoolean;/** * Created by zhenweiyu on 2017/5/19. */public class MsgQueueDispatcher {    private PriorityBlockingQueue<Runnable> mPriorityBlockingQueue;    private HandleThread mHandleThread;    private static volatile MsgQueueDispatcher mInstance;    private ExecutorService mMsgTaskExecutor;    private AtomicBoolean mExit;    private MsgQueueDispatcher(){        mPriorityBlockingQueue= new PriorityBlockingQueue<>();        mExit = new AtomicBoolean(false);        mHandleThread = new HandleThread();        mMsgTaskExecutor = Executors.newFixedThreadPool(15);    }    public static MsgQueueDispatcher getInstance(){        if(mInstance == null){            synchronized (MsgQueueDispatcher.class){                if(mInstance==null){                    mInstance = new MsgQueueDispatcher();                }            }        }        return mInstance;    }    public void startDispatcher(){        if(mHandleThread!=null){            if(!mHandleThread.isInterrupted()){                mExit.set(true);                mHandleThread.interrupt();            }            mExit.set(false);            mHandleThread.start();        }    }    public void stopDispatcher(){        mExit.set(true);        if(mHandleThread!=null){            mHandleThread.interrupt();        }    }    public void sendMsg(MsgRunnable runnable){        if(mPriorityBlockingQueue!=null) {            mPriorityBlockingQueue.offer(runnable);        }    }    class HandleThread extends Thread{        public HandleThread(){            super();        }        @Override        public void run() {            while (!mExit.get()){                if(mExit.get()){                    break;                }                try {                    System.out.println("waiting for msg......");                    Runnable runnable = mPriorityBlockingQueue.take();                    if(runnable!=null){                        System.out.println(String.format("------take msg %s  level %d------",                                ((MsgRunnable)runnable).getContent(),((MsgRunnable)runnable).getLevel()));                        if(mMsgTaskExecutor!=null){                            mMsgTaskExecutor.execute(runnable);                        }                    }                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }    static class MsgRunnable implements Runnable,Comparable<MsgRunnable>{        private int level;        private String content;        public MsgRunnable(String content,int level){            this.content = content;            this.level = level;        }        public int getLevel(){            return level;        }        public String getContent(){            return content;        }        @Override        public int compareTo(MsgRunnable o) {            if(this.level>o.level){                return -1;            }else if(this.level<o.level){                return 1;            }            return 0;        }        @Override        public void run() {            try {                System.out.println(String.format("sending msg %s,current level %d",content,level));                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

优先队列的操作对象必须实现Comparable接口,return -1 的表示优先级比较高

/** * Created by zhenweiyu on 2017/5/19. */public class MsgQueueDispatcherDemo {    public static void main(String []args){        MsgQueueDispatcher msgQueueDispatcher = MsgQueueDispatcher.getInstance();        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                for(int i=0;i<20;i++){                    MsgQueueDispatcher.MsgRunnable msgRunnable = new MsgQueueDispatcher.                            MsgRunnable(String.format("send msg %d",i),i);                    msgQueueDispatcher.sendMsg(msgRunnable);                }            }        });        thread.start();        try {            thread.join();        } catch (InterruptedException e) {            e.printStackTrace();        }        msgQueueDispatcher.startDispatcher();        //msgQueueDispatcher.stopDispatcher();    }}

可以看到结果是level为19的msg是先被取出的,而level = 0的是最后被取出的,而与初始入队的顺序没有关系

阅读全文
0 0
原创粉丝点击