zoukankan      html  css  js  c++  java
  • 线程之间的协作

    线程之间的协作

      当多个线程一起工作的时候,可能线程与线程之间存在执行的先后顺序,所以需要对线程进行协调。

    join()

      在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束

      对于以下代码,虽然 b 线程先启动,但是因为在 b 线程中调用了 a 线程的 join() 方法,b 线程会等待 a 线程结束才继续执行,因此最后能够保证 a 线程的输出先于 b 线程的输出。

    public class JoinExemple {
        public class A extends Thread{
            @Override
            public void run(){
                System.out.println("A run");
            }
        }
        public class B extends Thread{
            private A a;
            B(A a){
                this.a=a;
            }
            @Override
            public void run(){
                try{
                    a.join();
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println("B run");
            }
        }
        public static void main(String[]args){
            JoinExemple e=new JoinExemple();
            A a=e.new A();
            B b=e.new B(a);
            b.start();
            a.start();
        }
    }
    
    

    wait(),notify(),notifyAll()

      wait()notify()notifyAll()是Object类的方法,不是线程的方法,调用wait()使得线程满足某个条件后才能够继续运行,此时该线程会挂起,当另外的线程执行使得这个条件满足时会调用notify(),notifyAll()方法唤醒挂起的线程。

      wait(),notify(),notifyAll()只能在同步块或者同步方法中使用否则在运行时抛出 IllegalMonitorStateException

      使用 wait() 挂起期间,线程会释放锁。这是因为,如果没有释放锁,那么其它线程就无法进入对象的同步方法或者同步控制块中,那么就无法执行 notify() 或者 notifyAll() 来唤醒挂起的线程,造成死锁

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class WaitNotifyExemple {
        public class WaitExemple{
            public synchronized void before(){
                    System.out.println("before");
                    notifyAll();
                }
            public synchronized  void after(){
                try{
                    wait();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println("after");
            }
        }
        public static void main(String[]args){
            WaitNotifyExemple e=new WaitNotifyExemple();
            WaitExemple exemple=e.new WaitExemple();
            ExecutorService executorService= Executors.newCachedThreadPool();
            executorService.execute(()->exemple.after());
            executorService.execute(()->exemple.before());
            executorService.shutdown();
        }
    }
    

    wait()和sleep()区别

      wait()是Object方法sleep()是Thread方法,wait()会释放锁,而sleep()不会。

    await(),signal(),signalAll()

      java.until.concurrent包中提供了Condition类来实现线程之间的协调,可以调用await()方法使线程等待,其他的线程调用signal或者signalAll方法唤醒等待的线程。

      相比wait(),await()可以指定等待的条件,因此更加的灵活,使用Lock来获取一个Condition对象。

    package ConcurrentExemple;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class AwaitSignalExemple {
        public class AwaitExemple{
            Lock lock=new ReentrantLock();
            Condition condition=lock.newCondition();
            public void before(){
                lock.lock();
                try {
                    System.out.println("before");
                    condition.signalAll();
                }finally {
                    lock.unlock();
                }
            }
            public void after(){
                lock.lock();
                try{
                    condition.await();
                    System.out.println("after");
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }
        public static void main(String[]args){
            AwaitSignalExemple e=new AwaitSignalExemple();
            AwaitExemple waitExemple=e.new AwaitExemple();
            ExecutorService executorService= Executors.newCachedThreadPool();
            executorService.execute(()->waitExemple.after());
            executorService.execute(()->waitExemple.before());
            executorService.shutdown();
    
        }
    }
    
    
  • 相关阅读:
    操作系统学习之绪章
    20199311 2019-2020-2《网络攻防实践》第12周作业
    20199311 2019-2020-2《网络攻防实践》第10周作业
    20199311 2019-2020-2《网络攻防实践》第9周作业
    20199311 2019-2020-2《网络攻防实践》第8周作业
    20199311 2019-2020-2《网络攻防实践》第7周作业
    20199311 2019-2020-2《网络攻防实践》第6周作业
    20199311 2019-2020-2《网络攻防实践》第5周作业
    20199311 2019-2020-2《网络攻防实践》第4周作业
    2017-2018-2 20179215 密码与安全新技术期末总结
  • 原文地址:https://www.cnblogs.com/yjxyy/p/10704974.html
Copyright © 2011-2022 走看看