线程通讯休眠唤醒的几种方式

****1. Object 的 wait,notify,notifyAll

/**
 * 使用object的wait方法和notify方法以及notifyAll 方法必须依赖于synchronized 关键字的方法或代码块
 */
public class WaitThread {

    private int i=0;

    private Object object = new Object();
    /**
     * 奇数打印(里面描述内容同理使用于even()方法)
     */
    public void odd(){
        while (i<10){
            //打印奇数
             synchronized (object){
                 if (i%2==1){
                     System.out.println("奇数"+i);
                     i++;
                     //打印结束后通知其它当前锁对象线程执行
                      //object.notify(); 此处是奇偶方法抢锁用了notify()方法,但一般使用notifyAll()方法更稳妥
                     object.notify();
                 }else {
                     try {
                         //如果不是奇数就进入等待状态释放锁让其他线程获取锁执行
                         object.wait();
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }
        }
    }

    /**
     * 偶数打印
     */
    public void even(){
        while (i<10){
            //打偶数
            synchronized (object){
                if (i%2==0){
                    System.out.println("偶数"+i);
                    i++;
                    object.notify();
                }else {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
       final   WaitThread threads = new WaitThread();
        //开启奇数线程打印
        Thread thread1  =  new Thread(new Runnable() {
            @Override
            public void run() {
                threads.odd();
            }
        });

        Thread thread2 =  new Thread(new Runnable() {
            @Override
            public void run() {
                threads.even();
            }
        });

        thread1.start();
        thread2.start();
    }
}

2. Condition 的 await,signal ,signalAll**

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

public class ConditionDemo {

    private int i=0;

     /**
     * 这是手动锁类似synchronized 但比较灵活
     */
    private Lock lock = new ReentrantLock();

    private Condition condition =  lock.newCondition();

    /**
     * 奇数打印
     */
    public void odd(){
        while (i<10){
            //打印奇数
            //lock 加锁和解锁是手动的所以必须 是 lock.lock() 和  lock.unlock();成对出现不然容易造成死锁
            lock.lock();
              try {
                  if (i%2==1){
                      System.out.println("奇数"+i);
                      i++;
                      //唤醒另一个线程 signal 类似上面的 notify方法
                      condition.signal();
                  }else {
                      try {
                          //await 类似上面的wait 方法 描述不在赘述
                          condition.await();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }finally {
                  lock.unlock();
              }


        }
    }

    /**
     * 偶数打印
     */
    public void even(){
        while (i<10){
            //打偶数
               lock.lock();
                try{
                    if (i%2==0){
                        System.out.println("偶数"+i);
                        i++;
                        condition.signal();
                    }else {
                        try {
                            condition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }finally {
                     lock.unlock();
                }

        }
    }

    public static void main(String[] args) {
        final   WaitThread threads = new WaitThread();
        //开启奇数线程打印
        Thread thread1  =  new Thread(new Runnable() {
            @Override
            public void run() {
                threads.odd();
            }
        });

        Thread thread2 =  new Thread(new Runnable() {
            @Override
            public void run() {
                threads.even();
            }
        });

        thread1.start();
        thread2.start();
    }

3. CountDownLatch : 用于某个线程A等待若干个其他线程执行完之后,它才执行

import java.util.concurrent.CountDownLatch;

/**
 * countDownLatch某个线程等待其他线程完毕后,它在执行
 */
public class CountDownLatchDemo {

    private CountDownLatch countDownLatch = new CountDownLatch(3);

    /**
     * 运动员准备方法
     */
    public void player(){
        //1.获取线程运动员名称
        String name = Thread.currentThread().getName();
        //2.运动员准备
        System.out.println("运动员:"+name+"正在准备中!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //3.运动员准备完毕已就绪
        System.out.println("运动员:"+name+"准备完毕已就绪!");
        //每个运动员准备就绪后就 -- 即:countDownLatch.countDown()
        countDownLatch.countDown();
    }

    /**
     * 教练员方法
     */
    public  void coach(){
        //1.获取教练员名称
        String name = Thread.currentThread().getName();
        //2.教练员等待运动员准备
        System.out.println("教练员:"+name+"等地运动员准备");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("教练员:"+name+"开始训练");
    }

    public static void main(String[] args) {
       final CountDownLatchDemo countDownLatchDemo = new CountDownLatchDemo();
       Thread thread2 = new Thread(new Runnable() {
           @Override
           public void run() {
               countDownLatchDemo.player();
           }
       },"运动员一号");

        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                countDownLatchDemo.player();
            }
        },"运动员二号");

        Thread thread4 = new Thread(new Runnable() {
            @Override
            public void run() {
                countDownLatchDemo.player();
            }
        },"运动员三号");

        Thread thread5 = new Thread(new Runnable() {
            @Override
            public void run() {
                countDownLatchDemo.coach();
            }
        },"教练陈");

        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();

    }


}

4. CyclicBarrier: 一组线程等待某个状态之后再全部同时执行

import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class ThreeThreadStart {

    private CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

    public void startThread(){
        //1.打印新准备启动
         String name = Thread.currentThread().getName();
        System.out.println(name+"正在准备。。。");
        //2.调用CyclicBarrier 的方法await方法等线程全部准备完成
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        //3.打印线程启动完毕
        System.out.println(name+"已经启动完毕:"+new Date().getTime());
    }

    public static void main(String[] args) {
        ThreeThreadStart starts = new ThreeThreadStart();

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                starts.startThread();
            }
        },"线程1");

        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                starts.startThread();
            }
        },"线程2");

        Thread thread4 = new Thread(new Runnable() {
            @Override
            public void run() {
                starts.startThread();
            }
        },"线程3");

        thread2.start();
        thread3.start();
        thread4.start();
    }

}

5. Semaphore: 用于控制对某组资源的访问权限**

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

    static class Work implements Runnable{
        private int workNum ;// 工人工号
        [Semaphore 具体用法参考]
        (https://blog.csdn.net/carson0408/article/details/79475723)
        private Semaphore semaphore; //机器数

        public Work(int workNum, Semaphore semaphore) {
            this.workNum = workNum;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
           //1.工人获取机器
            try {
                semaphore.acquire();
                //2.打印线程,获取机器,开始工作
                String  name = Thread.currentThread().getName();
                System.out.println(name+"获取到机器,开始工作。。。。");
                //3.机器睡眠,模拟人工使用
                Thread.sleep(1000);
                //4.使用完毕,释放机器
                semaphore.release();
                System.out.println(name+"工人使用完毕,可以供其他工人使用");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
         int workers = 8;
         Semaphore semaphore = new Semaphore(3);
         for (int i=0;i<workers;i++){
             new Thread(new Work(i,semaphore)).start();
         }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值