@TOC

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

这三个也是面试常问的,作为线程通信的方法

1.CountDownLatch(CDL)

主要是用于一个线程等待其他完成后才继续执行。

  • 主要方法:await()、countDown()
CountDownLatch cdl = new CountDownLatch(2);

//第一个线程
new Thread(){
	public void run(){
		System.out.println("1111111");
		cdl.countDown();
	}
}.start();
//第二个线程
new Thread(){
	public void run(){
		System.out.println("22222222222221111111");
		cdl.countDown();
	}
}.start();

//主线程
cdl.await();
System0out.println("main执行!!!!!");

2.CyclicBarrier

回环栅栏:主要是用于多个线程在某个点/状态同时执行。

  • 主要方法:await()
int N = 4;
CyclicBarrier cb = new CyclicBarrier(N);
for(int i=0;i<N;i++){
	new Thread(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName() + "--------");
			cb.await();
			System.out.println(Thread.currentThread().getName() + "after-------");
		}
	}
}

注:其await(long timeout,TimeUnit unit)重载方法,让已到达的线程等待至一定的时间,如果还没有到达指定的数量,则这些开始执行。

3.Semaphore

信号量:主要控制访问临界资源的线程数量

  • 主要方法:acqurie()、release()
//工人数
int N = 8;
//机器或者说是资源数
Semaphore sp = new Semaphore (5);
for(int i=0;i<N;i++){
	new Thread(){
		@Override
		public void run(){
			sp.acquire();
			System.out.println("获取机器成功!!");
			sp.release();
			System.out.println("释放机器!!");
		}
	}
}

总结: 前两者主要是实现线程之间的等待,而semaphore主要是控制对资源的访问

4.生产者、消费者

开始撸代码了:

4.1 Synchronized

public class MyTest01 {


    public class Data{
        private  int num = 0;
        public synchronized void product() throws InterruptedException {
            while(num!=0){
                this.wait();
            }
            num++;
            System.out.println("生产一个!");
            this.notify();
        }
        public synchronized void consume() throws InterruptedException {
            while(num==0){
                this.wait();
            }
            num--;
            System.out.println("消费一个!");
            this.notify();
        }
    }
     @Test
    public void test(){
        final Data data = new Data();
        //final DataLock data = new DataLock();
        //生产者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.product();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //消费者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }
}

4.2 ReentrantLock

public class MyTest01 {


     public class DataLock{
        private  int num = 0;
        ReentrantLock lock = new ReentrantLock();
        Condition cd = lock.newCondition();
        //Condition cd2 = lock.newCondition();

        public  void product() throws InterruptedException {
            lock.lock();
            while(num!=0){
                cd.await();
            }
            num++;
            System.out.println("生产一个!");
            cd.signalAll();
            lock.unlock();
        }
        public void consume() throws InterruptedException {
            lock.lock();
            while(num==0){
                cd.await();
            }
            num--;
            System.out.println("消费一个!");
            cd.signal();
            lock.unlock();
        }
    }
    
     @Test
    public void test(){
        //final Data data = new Data();
        final DataLock data = new DataLock();
        //生产者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.product();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //消费者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }
}