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

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

  • 相关阅读:
    《Programming WPF》翻译 第8章 1.动画基础
    一些被遗忘的设计模式
    《Programming WPF》翻译 第4章 数据绑定
    《Programming WPF》翻译 第3章 控件
    《Programming WPF》翻译 第5章 样式和控件模板
    《Programming WPF》翻译 第7章 绘图
    《Programming WPF》翻译 第9章 自定义控件
    《Programming WPF》翻译 第7章 绘图 (2)
    《Programming WPF》翻译 第8章 前言
    关于Debug和Release之本质区别
  • 原文地址:https://www.cnblogs.com/cutter-point/p/8504515.html
Copyright © 2011-2022 走看看