Condition在lock中实现线程通讯

package com.thread_test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by zhen on 2017-06-06.
 */
public class ConditionTest {

    /**
     * Condition 的功能类似在传统线程技术中的Object.wait和Object.notify的功能。在等待Condition时,允许发生“虚拟唤醒”,
     * 这通常作为普通平台语义的让步。
     * condition的await方法与signal方法类似于Object的wait和notify方法
     * 如果只是这样,那么Condition的出现有什么意义呢?
     *
     */

    public static void main(String[] args){
        final Business business = new Business();
        new Thread(new Runnable(){
            public void run() {
                for(int i = 1; i <= 50; i++){
                    business.sub1(i);
                }
            }
        }).start();
        new Thread(new Runnable(){
            public void run() {
                for(int i = 1; i <= 50; i++){
                    business.sub2(i);
                }
            }
        }).start();

        for(int i = 1; i <= 50; i++){
            business.main(i);
        }

    }

    static class Business{
        private static int runSeq = 0;
        private Lock lock = new ReentrantLock();
        private Condition main = lock.newCondition();
        private Condition sub1 = lock.newCondition();
        private Condition sub2 = lock.newCondition();

        public void main(int i){
            lock.lock();
            while(runSeq != 0){
                try {
                    main.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try{
                System.out.println("main thread run time is " + i);
                for(int j = 1; j <= 100; j++){
                    System.out.println("main thread out " + j);
                }
                runSeq = 1;
                sub1.signal();
            }finally{
                lock.unlock();
            }

        }

        public void sub1(int i) {
            lock.lock();
            try {
                while (runSeq != 1) {
                    try {
                        sub1.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("sub1 thread run time is " + i);
                for (int j = 1; j <= 10; j++) {
                    System.out.println("sub1 thread out " + j);
                }
                runSeq = 2;
                sub2.signal();
            } finally {
                lock.unlock();
            }
        }

        public void sub2(int i){
            lock.lock();
            try{
                while(runSeq != 2){
                    try {
                        sub2.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("sub2 thread run time is " + i);
                for(int j = 1; j <= 10; j++){
                    System.out.println("sub2 thread out " + j);
                }
                runSeq = 0;
                main.signal();
            }finally{
                lock.unlock();
            }

        }

        /**
         * 缓冲队列问题
         *  需求:呼机的中转机器,接受话务员的输入指令,使用发布机向外界发布消息信号,发布机各种限制下只能每秒1条发布,所以需要一个缓冲队列
         *  分析:
         *      队列的实现使用数组
         *      多线程。多个线程进行写入,1个线程进行发布。
         *          写入的顺序从0到数组长度,到底了从0又开始循环。如果下一个位置已经有元素了,等待,通知发布。
         *          发布也是从0开始到数组长度,到底了又开始循环。如果下一个位置没有元素了,等待,通知写入。
         *
         *  Condition可以存在多个。
         *
         */
        class BoundBuffer{
            final Lock lock = new ReentrantLock();
            final Condition notFull = lock.newCondition();
            final Condition notEmpty = lock.newCondition();

            final Object[] items = new Object[100];
            int putptr, takeptr, count;

            public void put(Object x) throws InterruptedException {
                lock.lock();
                try{
                    while(count == items.length){
                        notFull.await();
                    }
                    items[putptr] = x;
                    if(++putptr == items.length){
                        putptr = 0;
                    }
                    ++count;
                    notEmpty.signal();
                }finally{
                    lock.unlock();
                }
            }

            public Object take() throws InterruptedException {
                lock.lock();
                try{
                    while(count == 0){
                        notEmpty.await();
                    }
                    Object x = items[takeptr];
                    if(++takeptr == items.length){
                        takeptr = 0;
                    }
                    -- count;
                    notFull.signal();
                    return x;
                }finally {
                    lock.unlock();
                }
            }
        }

















    }


}

 

posted @ 2017-06-06 13:18  guodaxia  阅读(145)  评论(0)    收藏  举报