线程间协作

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. Python核心技术与实战——十九|一起看看Python全局解释器锁GIL

    我们在前面的几节课里讲了Python的并发编程的特性,也了解了多线程编程.事实上,Python的多线程有一个非常重要的话题——GIL(Global Interpreter Lock).我们今天就来讲一 ...

  2. nginx第二天

    nginx配置文件 配置文件结构 全局配置(user.worker_processes.error_log.pid) events(网络连接相关,worker_connections) http(最重 ...

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

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

  4. django 之视图层及模板层 04

    目录 视图层 render方法是Template和Contex两个对象的组合使用 JsonResponse对象 CBV及源码分析 CBV 加装饰器的方式 模板层 模板语法传值 模板语法 变量 过滤器( ...

  5. [CF1105E] Helping Hiaset

    问题描述 你在某社交网站上面注册了一个新账号,这个账号有\(n(n\leq 10^5)\)次记录.要么就是你更改过一次ID,要么就是一个ID为\(s(|s|\leq 40)\)的朋友访问过你的空间. ...

  6. 【leetcode】1272. Remove Interval

    题目如下: Given a sorted list of disjoint intervals, each interval intervals[i] = [a, b] represents the ...

  7. Python CGI编程Ⅵ

    GET和POST方法 浏览器客户端通过两种方法向服务器传递信息,这两种方法就是 GET 方法和 POST 方法. 使用GET方法传输数据 GET方法发送编码后的用户信息到服务端,数据信息包含在请求页面 ...

  8. C# 从Object对象中读取属性的值

    https://www.cnblogs.com/xbblogs/p/7739483.html

  9. 悲观锁,乐观锁以及MVCC

    在上文中,我们探讨了MySQL不同存储引擎中的各类锁,在这篇文章中我们将要讨论的是MySQL是如何实现并发控制的.并发问题有三种,分别为: 读-读,不存在任何问题 读-写,有隔离性问题,可能遇到脏读( ...

  10. rm:删除文件或目录

    在使用 rm 命令删除文件或目录时,系统不会产生任何提示信息.此命令的基本格式为:rm[选项] 文件或目录 选项: -f:强制删除(force),和 -i 选项相反,使用 -f,系统将不再询问,而是直 ...