• java并发编程 线程间协作


    线程间协作

    1. 等待和通知

    等待和通知的标准形式
    等待方:

    1. 获取对象锁
    2. 循环中判断条件是否满足,不调用wait()方法
    3. 条件满足执行业务逻辑

    通知方:

    1. 获取对象所
    2. 改变条件
    3. 通知所有等待在对象的线程

    2. wait、notify/notifyAll

    wait:导致当前线程等待,直到有其他线程调用当前同步监视器的notify()notifyall()方法来唤醒此线程。wait()方法有三种形式——无时间参数的wait(一直等待,直到其他线程通知),带毫秒参数的waut()和带毫秒和纳秒参数的wait(指定时间后自动苏醒)
    notify:唤醒在此同步监视器上等待的单个线程,如果有多个线程在此同步监视器上等待,那么只会随机的呼唤其中的一个线程;等待的线程只是被激活,但是必须得再次获得锁才能继续往下执行,也就是说只要锁没被释放,原等待线程因为为获取锁仍然无法继续执行。
    notifyAll:唤醒所有等待在此同步监视器上的线程,所有线程处于激活状态。

    wait()方法、notify()方法和notiftAll()方法来自于java.lang.Object,用于协调多线程对共享数据的存取,所以只能在同步方法或者同步块中使用,否则抛出异常(IllegalMonitorStateException)。

    3. join

    Thread 提供了一个让一个线程等待另一个线程执行完成的方法——join()方法;当程序执行中调用其它线程的join()方法时,调用线程将被阻塞,直到join()方法加入的join线程执行完毕为止。

    static class JoinQueue implements Runnable {
        private Thread thread;
        public JoinQueue(Thread thread) {
            this.thread = thread;
        }
        @Override
        public void run() {
            try {
                thread.join();
                System.out.println(Thread.currentThread().getName()+" terminted.");
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        Thread previous = Thread.currentThread();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new JoinQueue(previous), String.valueOf(i));
            System.out.println(" thread " + previous.getName() + " is in front of " + thread.getName());
            thread.start();
            previous = thread;
        }
        Thread.sleep(2000);
        System.out.println(Thread.currentThread()+" done");
    }
    

    4. 调用yield()、sleep()、wait()、notify()等对锁的影响

    线程在执行yield()以后,持有的锁是不释放的;
    sleep()方法被调用后,持有的锁是不释放的;
    wait()方法调用前线程必须要持有的锁,调用wait()方法后,锁就会被释放,当wait()方法返回时候,线程会重新持有锁;
    调用notify()方法之前,必须要持有锁,调用notify()方法本身不会释放锁的 。

  • 相关阅读:
    内网或无域名服务器集成微信公众号接口
    记录一次重新学习SetInternal和SetTimeout
    SQLServer日志过大导致还原失败的解决方案
    批量修改SQLServer数据库表字段属性
    收缩SQLServer数据库解决日志占用空间过大(2008R2以上版本)
    SAP GUI安装出现ocx错误提示的解决办法
    .NetCore自动转换枚举类显示自定义中文名称
    EFCore-脚手架Scaffold发生Build Failed问题的终极解决
    .NetCore自定义WebAPI返回Json的格式大小写的三种方式
    存储过程模糊搜索,按匹配率排序初探
  • 原文地址:https://www.cnblogs.com/huizhipeng/p/12079958.html
Copyright © 2020-2023  润新知