线程间协作

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()方法本身不会释放锁的 。

java并发编程 线程间协作的更多相关文章

  1. Java并发编程:线程间通信wait、notify

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  2. java并发编程 线程基础

    java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...

  3. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  4. java并发编程 | 线程详解

    个人网站:https://chenmingyu.top/concurrent-thread/ 进程与线程 进程:操作系统在运行一个程序的时候就会为其创建一个进程(比如一个java程序),进程是资源分配 ...

  5. Java并发编程:线程和进程的创建(转)

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  6. Java中详述线程间协作

    线程协作 首先引入一段代码: package 线程间数据共享; import java.util.Date; public class Watch { private static String ti ...

  7. java中关于线程间协作所用关键字synchronized,wait,notify的用法

    wait/notify()关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景. 例如,一个线程一直等待直到队列中有一个组件能够处理:当组件添加到队列 ...

  8. Java并发编程——线程安全及解决机制简介

    简介: 本文主要介绍了Java多线程环境下,可能会出现的问题(线程不安全)以及相应的解决措施.通过本文,你将学习到如下几块知识: 1. 为什么需要多线程(多线程的优势) 1. 多线程带来的问题—线程安 ...

  9. Java并发编程——线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...

随机推荐

  1. 网络编程与socket

    .互联网协议 互联网协议又称为网络七层协议,OSI七层协议,OSI是一个世界标准组织. OSI七层协议: - 应用层 - 表示层 - 会话层 - 传输层 - 网络层 - 数据链路层 - 物理连接层 学 ...

  2. 如何制作chrome浏览器插件之一

    方法如下: 1.创建一个单独的文件夹,比如说为百度贴吧开发一个插件,就叫TiebaAddion.之后在这个文件夹里创建一个名字为"manifest.json"的文件,在里面写上如下 ...

  3. vue 里面异步加载高德地图

    前言 关于Vue 里面使用异步加载高德地图 项目中其实只有几处需要用到地图,不需要全局引入 在index文件中引入js会明显拖慢首屏加载速度,虽然可以使用异步加载script的方式解决,但是始终觉得不 ...

  4. Java中遍历HashMap方式

    本教程将为你展示Java中HashMap的几种典型遍历方式. 如果你使用Java8,由于该版本JDK支持lambda表达式,可以采用第5种方式来遍历. 如果你想使用泛型,可以参考方法3.如果你使用旧版 ...

  5. php l练习(写着玩)

    需求:假设今天24号,今天发表的评论显示几小时前发布,23号发布的显示 昨天几点发布的,再往前的就直接显示年月日. date_default_timezone_set('PRC'); // $crea ...

  6. 【PKUSC2019】树染色【线段树合并】【树形DP】

    Description 给出一棵n个点的树,现在有m种颜色,要给每个节点染色,相邻节点不能同色. 另外有k条限制,形如x号点不能为颜色y 同一节点有可能有多条限制. 求方案数对998244353取模的 ...

  7. HGOI 20190822 OCWA提高组模拟赛二

    Problem A 快递 根节点为$1$ , 含有$n$个节点的树,每一条边都有一段开放的时间$[s_i,e_i]$,和经过需要的时间. 有$q$组询问,每一次在时刻$t_i$出发从根节点出发走到第$ ...

  8. 16位masm汇编实现记忆化递归搜索斐波那契数列第50项

    .model small ;递归fib,使用压缩BCD码,小端派 .data y1 byte 6 dup(0) y2 byte 6 dup(0) vis byte 1,1,1,61 dup(0) ;便 ...

  9. 动态调用WebService接口的几种方式

    一.什么是WebService? 这里就不再赘述了,想要了解的====>传送门 二.为什么要动态调用WebService接口? 一般在C#开发中调用webService服务中的接口都是通过引用过 ...

  10. 一、让自己习惯C++

    写在前面 第一遍看<Effective C++>时,在准备暑期实习生的招聘,没有时间好好地捋一下,将一些要点记录下来.现在实习回来,重读此书,并记录一些要点,为今后的复习亦或是学习铺垫. ...