线程间协作

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. 安装theano时候发现报错:cannot install ''numpy'.It is a distutils installed project and thus we cannot ...

    发现我安装theano的时候需要numpy需要1.9以上版本,而我之前自带的numpy是1.8版本,所以版本有问题.根本原因是theano需要的numpy版本不符合要求,但是numpy已经安装过了,所 ...

  2. 【codevs1690】开关灯 线段树

    这道题需要支持区间修改和区间询问,因此采用线段树加以维护. 由于求的是开着的灯的数目,因此维护sum:区间[ l , r ]中开着的灯的数目. tag取做0/1,表示区间是否反转,在进行标记下传时,如 ...

  3. 通过实现接口runnable实现多线程

    实现Runnable接口实现多线程的步骤(1)编写类实现Runnable接口(2)实现run(方法(3)通过Thread类的start(方法启动线程 静态代理模式Thread >代理 角色MyR ...

  4. 扩展Puppet – 建立Puppet CA集群

    扩展Puppet – 建立Puppet CA集群  (1 votes, average: 5.00 out of 5) 588 views 2012 年 3 月 4 日Puppet.运维ca.mast ...

  5. Linux系统上java调用C++ so库文件

      PART1:     java中使用jna替代jni调用c++/c生成的 dll/so库文件需要做的事项 1.引入JNA依赖或者直接下载JNAjar包           <!-- http ...

  6. C# 常用方法—— 32位MD5加密

    其他常用方法详见:https://www.cnblogs.com/zhuanjiao/p/12060937.html /// <summary> /// 32位MD5加密(小写) /// ...

  7. vue 绑定class、v-bind:style(对象语法、数组语法)

    绑定 HTML Class 我们可以传给 v-bind:class 一个对象,以动态地切换 class: 内联样式在模板里 <div id="div1" :class=&qu ...

  8. LVS 学习

    参考网站:http://www.linuxvirtualserver.org 一,部分概念 服务器集群系统: 通过高性能网络或局域网互联的服务器集群正成为实现高可伸缩的.高可用网络服务的有效结构,这种 ...

  9. HTML+CSS之光标悬停图片翻转效果

    设计思路:         首先做一个包括图片和说明文字的简单的页面结构,然后再设置它的变换.将变换的元素,即照片和文字放在一个父容器里面,这就需要四个父容器 ,再将这四个父容器放在最外层的舞台上面进 ...

  10. SpringBoot项目中,异常拦截

    SpringBoot自带异常拦截@ControllerAdvice 1.创建一个SellerExceptionHandler类打上@ControllerAdvice标签 @ControllerAdvi ...