线程顺序执行

线程顺序执行采用Lock锁的方式

  Lock与Synchronized的区别:

  1. Synchronized 内置的Java关键字, Lock 是一个Java类
  2. Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
  3. Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
  4. Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;
  5. Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以 自己设置);
      1. Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!
        public class LockSortRun {
            public static void main(String[] args) {
                   C c =new C();
                 new Thread(()->{
                    for (int i = 0; i < 10; i++) {
                        c.A1();
                    }
                },"A").start();
                new Thread(()->{
                    for (int i = 0; i < 10; i++) {
                        c.A2();
                    }
                },"B").start();new Thread(()->{
                    for (int i = 0; i < 10; i++) {
                        c.A3();
                    }
                },"C").start();
        
        }
        }
        class C{
            private  int number = 0;
            Lock lock = new ReentrantLock();
            Condition condition1 = lock.newCondition();   //Condition精确的通知和唤醒线程,指定线程执行方向
            Condition condition2 = lock.newCondition();  //Condition中的await()与signal()方法 类似于 wait()与notify()方法
            Condition condition3 = lock.newCondition();  //等待 唤醒
            public  void A1() {
                lock.lock();
                try {
                    while (number != 0 ){                 //这里使用while而不使用if的原因是 防止虚假唤醒
                        condition1.await();               //判断number是否为空 不是则等待
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {                   //操作写在finally中,无论try是否抛出异常都会执行
                    System.out.println(Thread.currentThread().getName()+"=>AAA");
                    number = 1;                           //设置number值
                    condition2.signal();                  //指定执行线程condition2 并且在condition2中做判断
                    lock.unlock();                        //解锁
                }
            }
            //-1
            public  void A2() {
                lock.lock();
                try {
                    while (number!=1){ // 1     问题存在,A B C D 4 个线程! 虚假唤醒 if 改为 while 判断 等待
                        condition2.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    number = 2;
                    System.out.println(Thread.currentThread().getName()+"=>BBB");// 通知其他线程,我执行完毕了
                    condition3.signal();
                    lock.unlock();
                }
        
            }
            public  void A3() {
                lock.lock();
                try {
                    while (number!=2){ // 1     问题存在,A B C D 4 个线程! 虚假唤醒 if 改为 while 判断 等待
                        condition3.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    number = 0;
                    System.out.println(Thread.currentThread().getName()+"=>CCC");// 通知其他线程,我执行完毕了
                    condition1.signal();
                    lock.unlock();
                }
        
            }
        }

         

posted @ 2020-06-30 22:25  张张小张  阅读(164)  评论(0)    收藏  举报