zoukankan      html  css  js  c++  java
  • 【并发】3、LockSupport阻塞与唤醒,相较与wait和notify

    我们可以使用wait和notify分别对象线程进行阻塞或者唤醒,但是我们也可以使用LockSupport实现一样的功能,并且在实际使用的时候,个人感觉LockSupport会更加顺手

    范例1,wait与notify

    class WaitTest1 {
        
        static class ThreadA extends Thread {
            public ThreadA(String name) {
                super(name);
            }
    
            @Override
            public void run() {
                synchronized (this) {
                    System.out.println(Thread.currentThread().getName() + " wakup others");
                    this.notify(); // 唤醒当前线程对象
                    for (int i = 0; i < 10; ++i) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("唤醒当前线程对象之后" + i);
                    }
                }
    
                for (int i = 0; i < 10; ++i) {
                    System.out.println("唤醒当前线程对象,释放锁之后前" + i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("唤醒当前线程对象,释放锁之后" + i);
                }
    
            }
        }
        
        public void mian1() {
            ThreadA ta = new ThreadA("ta");
            
            //因为wait需释放锁,所以必须在synchronized中使用(没有锁定则么可以释放?没有锁时使用会抛出IllegalMonitorStateException(正在等待的对象没有锁))
            synchronized (ta) {
                try {
    
                    System.out.println(Thread.currentThread().getName() + " start ta");
                    ta.start();
    
                    System.out.println(Thread.currentThread().getName() + " block");
                    // 主线程等待,释放当前线程锁
                    ta.wait();
    
                    System.out.println(Thread.currentThread().getName() + " continue");
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

     运行结果:

    范例2,locksupport

    class LockSupportTest1 {
        private static Thread mainThread;
        
        static class ThreadA extends Thread {
            public ThreadA(String name) {
                super(name);
            }
    
            @Override
            public void run() {
                synchronized (this) {
                    System.out.println(Thread.currentThread().getName() + " wakup others");
    //                this.notify(); // 唤醒当前线程对象
                    LockSupport.unpark(mainThread);  //this,这里就不能使用this了,如果这里使用this,那么其实并没有释放这个对象的锁,释放的对象是ta的锁,那就会造成死锁
                    for (int i = 0; i < 10; ++i) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("唤醒当前线程对象之后" + i);
                    }
                }
    
                for (int i = 0; i < 10; ++i) {
                    System.out.println("唤醒当前线程对象,释放锁之后前" + i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("唤醒当前线程对象,释放锁之后" + i);
                }
    
            }
        }
        
        public void main1() {
            ThreadA ta = new ThreadA("LockSupportTest1");
            //获取当前主线程对象
            mainThread = Thread.currentThread();
            
            System.out.println(Thread.currentThread().getName() + " start ta");
            ta.start();
            
            System.out.println(Thread.currentThread().getName()+" block");
            
            //对主线程进行阻塞
            LockSupport.park(mainThread);
            
            System.out.println(Thread.currentThread().getName()+" continue");
            
        }
        
    }

    效果展示:

     两者相比我们就会发现,

    1、locksupport不需要先进入对应的同步锁,也就是synchronize获取当前锁,然后才能使用wait进行释放

    2、locksupport不局限在本线程中,更感觉是跳脱在线程外,对线程进行操控,不想synchronize中的notify,在没有退出同步代码块之前,这个锁实际上还是当前线程占用的,不管是否执行了notify

      只有在退出了同步代码块,这个锁才会真正的被释放

  • 相关阅读:
    土地出让金骤降是“危”还是“机”?
    EasyMonkeyDevice vs MonkeyDevice&amp;HierarchyViewer API Mapping Matrix
    Keepalived+Lvs+Mysql主主复制
    【SDUT 3038】迷之博弈
    js面向对象编程:if中能够使用那些作为推断条件呢?
    crm使用url打开窗口视图
    让你的javascript函数拥有记忆功能,降低全局变量的使用
    crm操作知识库文章实体
    技术揭秘12306改造(一):尖峰日PV值297亿下可每秒出票1032张-CSDN.NET
    大众点评的大数据实践-CSDN.NET
  • 原文地址:https://www.cnblogs.com/cutter-point/p/8504515.html
Copyright © 2011-2022 走看看