Thread之一:线程生命周期及五种状态

Thread之二:sleep、wait、yield、join

juc线程池原理(四): 线程池状态介绍

一、回顾下概念

Java中的多线程是一种抢占式的机制而不是分时机制。线程主要有以下几种状态:新建,就绪,运行,阻塞,死亡。抢占式机制指的是有多个线程处于就绪状态,但是只有一个线程在运行。
 

1.sleep()方法

  在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。

  sleep()使当前线程进入阻塞状态,在指定时间内不会执行。

2.wait()方法

  在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。

  当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。

  唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。

  waite() 和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生 IllegalMonitorStateException的异常。

3.yield方法

  暂停当前正在执行的线程对象。

  yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

  yield()只能使同优先级或更高优先级的线程有执行的机会。

4.join方法

  等待该线程终止。

  等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

二、线程同步

一个线程结束的标志是:run()方法结束。
一个机锁被释放的标志是:synchronized块或方法结束。
当有多个线程访问共享数据的时候,就需要对线程进行同步。线程同步相关的方法中的几个主要方法的按照所属可以分成:
  • Thread类的方法:sleep(),yield()等
  • Object的方法:wait()和notify()、notifyAll()等

Object中的对象头存放的锁信息在控制同步访问时使用。见《java对象在内存中的结构(HotSpot虚拟机)》和《Synchronized之二:synchronized的实现原理

Wait()方法和notify()方法:当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去了对象的机锁。当它被一个notify()方法唤醒时,等待池中的线程就被放到了锁池中。该线程从锁池中获得机锁,然后回到wait()前的中断现场。
 
Thread类中的方法:
由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁。所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象。而wait()方法则会在线程休眠的同时释放掉机锁,其他线程可以访问该对象。
Yield()方法:是停止当前线程,让同等优先权的线程运行。如果没有同等优先权的线程,那么Yield()方法将不会起作用。
join()方法:是由一个线程调用另一个线程,调用线程等待被调用线程终止。
 

sleep()与wait()的共同点及不同点:

共同点: 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
不同点: Thread.sleep(long)可以不在synchronized的块下调用,而且使用Thread.sleep()不会丢失当前线程对任何对象的同步锁(monitor);
              object.wait(long)必须在synchronized的块下来使用,调用了之后失去对object的monitor, 这样做的好处是它不影响其它的线程对object进行操作。

举个java.util.Timer的例子来说明。

private void main Loop() {
while (true) {
....
synchronized(queue) {
.....
if (!taskFired) // Task hasn't yet fired; wait
queue.wait(executionTime - currentTime);
}
}

在这里为什么要使用queue.wait(),而不是Thread.sleep(), 是因为暂时放弃queue的对象锁,可以让允许其它的线程执行一些同步操作。如:

private void sched(TimerTask task, long time, long period) {
synchronized(queue) {
...
queue.add(task);
}
}

但是正如上篇文章讲到的,使用queue.wait(long)的前提条件是sched()动作执行的时间很短,否则如果很长,那么queue.wait()不能够按时醒来。

Thread之二:sleep、wait、yield、join的更多相关文章

  1. Java多线程系列 基础篇10 wait/notify/sleep/yield/join

    1.Object类中的wait()/notify()/notifyAll() wait(): 让当前线程处于Waiting状态并释放掉持有的对象锁,直到其他线程调用此对象的线程notify()/not ...

  2. Object的wait/notify/notifyAll&&Thread的sleep/yield/join/holdsLock

    一.wait/notify/notifyAll都是Object类的实例方法 1.wait方法:阻塞当前线程等待notify/notifyAll方法的唤醒,或等待超时后自动唤醒. wait等待其实是对象 ...

  3. JAVA 多线程随笔 (二) sleep, yield, join, wait 和notify

    这里先说明一下锁对象,如果一个类比如Person里的方法都有synchronized来修饰,那么每一个方法的锁对象就是Person的一个实例person. 锁对象也可以针对某个特定的实例, 比如syn ...

  4. java ---线程wait/notify/sleep/yield/join

    一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...

  5. Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  6. 016 sleep,wait,yield,join区别

    1.线程通常有五种状态,创建,就绪,运行.阻塞和死亡状态.2.阻塞的情况又分为三种:(1).等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中.进入 ...

  7. 【转】Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...

  8. 线程间的协作(wait/notify/sleep/yield/join)(五)

    一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...

  9. Java中sleep,wait,yield,join的区别

    sleep() wait() yield() join()用法与区别   1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程 ...

随机推荐

  1. 基于ACCESS和ASP的SQL多个表查询与计算统计代码(一)

    近期在写几个关于"Project - Subitem - Task"的管理系统,说是系统还是有点夸大了,基本就是一个多表查询调用和insert.update的数据库操作.仅仅是出现 ...

  2. eclipse工具栏sdk和avd图标

    打开菜单Window -> Customize Perspective -> Command Groups Availability -> 勾选Android SDK and AVD ...

  3. VS2010配置QT5.5.0开发环境

    一.官网下载QT和qtvsaddin插件 网址:http://www.qt.io/download-open-source/ 1. 2. 3. 得到下载的安装包,点击安装就能够了 watermark/ ...

  4. kubernetes调度之资源耗尽处理配置

    系列目录 本篇将介绍如何使用kubelet处理资源耗尽的情况 当可用的计算机资源非常低的时候,kubelet仍然要保证节点的稳定性.当处理不可压缩的计算机资源(比如内存或磁盘空间)时,这尤其重要,当这 ...

  5. 宜人贷蜂巢ELK Stack之elasticsearch权限探索

    前言 上文<宜人贷蜂巢API网关技术解密之Netty使用实践>提到了,API网关“承外对内”,将外部请求,转发到内部各个抓取服务.在网关中,不仅可以做鉴权.加解密.路由.限流功能:如果想了 ...

  6. Mac 怎么打开两个终端

    把光标移到终端上,然后Command+N 启动maven  : mvn tomcat7:run

  7. poj3040(双向贪心)

    Allowance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1540   Accepted: 637 Descript ...

  8. UVA - 1045 The Great Wall Game(二分图最佳完美匹配)

    题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...

  9. Topcoder SRM 638 DIV 2 (大力出奇迹)

    水题,就是一个暴力.大力出奇迹. Problem Statement   There is a narrow passage. Inside the passage there are some wo ...

  10. mac下使用gnu gcc

    1 mac下安装gnu gcc brew search gcc brew install gcc@6 2 mac下编写c/c++代码所需的标准库和头文件 2.1 标准c++的库的头文件都是标准化了的, ...