线程之间的协作

线程之间的协作

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

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();

    }
}

转载于:https://www.cnblogs.com/yjxyy/p/10704974.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值