1.概述

使用Thread相对来说比较简单,没有什么成本,但是通常来说,我们使用线程基本就是覆写run方法,然后调用线程对象的start函数启动线程。

对于面试人员来说,这些都不是面试官会问到的问题,而线程的wait、sleep、join、yied这几个函数可问的就比较多了。

函数名 作用
wait    

当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁,使得其他线程可以访问。用户可以使用notify、notifyAll或者指定睡眠时间来唤醒当前等待池中的线程。

注意:wait()、notify()、notifyAll()必须放在synchronized block中,否则会抛出异常

sleep    该函数是Thread的静态函数,作用是使调用线程进入睡眠状态。因为sleep()是Thread类的Static方法,因此他不能改变对象的机锁。所以,当在一个Sychronized块中调用sleep()方法,线程虽然休眠了,但是对象的机锁并没有释放,其他线程无法访问这个对象(即使睡着也持有对象锁)
join 等待目标线程执行完成之后再继续执行
yield 线程礼让。目标线程由运行状态转换为就绪状态,也就是让出执行权限,让其他线程得以优先执行,但其他线程能否优先执行是未知数

2.实际运用

(1)wait、notify

public class ThreadFunTest {
private static Object sLockObject = new Object(); static void waitAndNotifyAll() {
System.out.println("主线程运行");
Thread thread = new WaitThread();
thread.start();
long startTime = System.currentTimeMillis();
try {
synchronized (sLockObject) {
System.out.println("主线程等待");
sLockObject.wait();
}
} catch (Exception ignored) { }
long timsMs = (System.currentTimeMillis() - startTime);
System.out.println("主线程继续-->等待耗时:" + timsMs + "ms");
} static class WaitThread extends Thread {
@Override
public void run() {
try {
synchronized (sLockObject) {
Thread.sleep(3000);
sLockObject.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
ThreadFunTest.waitAndNotifyAll();
}
}

执行结果:

在waitAndNotifyAll()函数中,会启动一个WaitThread线程,在该线程中将会调用sleep函数睡眠3秒,线程启动后在主线程调用sLockObject的wait函数,使主线程进入等待状态,此时将不会继续执行。等WaitThread在run函数睡眠3秒后会调用sLockObject的notifyAll函数,此时就会重新唤醒正在等待中的主线程,因此会继续执行下去。

 wait、notify机制通常用于等待机制的实现,当条件为满足时调用wait进入等待状态,一旦条件满足,调用notify或notifyAll唤醒等待的线程继续执行。

(2)join

与wait、sleep的浅显易懂不同的是join的作用并不那么直观,也许就是这个原因,使得join函数并不那么容易理解。join函数的原始解释为”Blocks the current Thread(Thread.currentThread())until the receiver finishes its execution and dies“,意思就是阻塞当前调用join函数时所在的线程,直到接收线程执行完毕后再继续。

static void joinDemo() {
Worker worker1 = new Worker("work-1");
Worker worker2 = new Worker("work-2");
worker1.start();
System.out.println("启动线程1");
try{
//调用work1的join函数,主线程会阻塞直到work1执行完成
worker1.join();
System.out.println("启动线程2");
//再启动线程2,并且调用线程2的join函数,主线程会阻塞直到worker2执行完成
worker2.start();
worker2.join();
}catch (Exception ignored){ }
System.out.println("主线程继续执行");
} static class Worker extends Thread {
public Worker(String name) {
super(name);
} @Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("work in " + getName());
}
} public static void main(String[] args) {
ThreadFunTest.joinDemo();
}

执行结果:

这是因为再joinDemo函数中,首先创建了两个子线程,然后启动了worker1,下一步再调用worker1的join函数。此时主线程进入阻塞状态,一直到worker1执行完毕后才开始继续执行。因为Worker的run函数会睡眠2秒,因此,在主线程中每次调用join实际上都会阻塞2秒,直到run执行完毕再继续。所以,上述逻辑为启动线程1--等待线程1执行完成--启动线程2--等待线程2执行完成--继续执行主干代码。

(3)yied

yied函数与join类似,官方解释为”Causes the calling Thread to yield execution time to another Thread that is read to run“。意思是使调用该函数的线程让出执行时间给其他已经就绪状态的线程。我们知道,线程的执行是有时间片的,每个线程轮流占用CPU固定的时间,执行周期到了之后就让出执行权给其他线程。而yield的功能就是主动让出线程的执行权给其他线程,其他线程能否得到优先执行就得看各个线程的状态了。示例:

static void yieldDemo() {
YieldThread t1 = new YieldThread("thread-1");
YieldThread t2 = new YieldThread("thread-2");
t1.start();
t2.start();
} static class YieldThread extends Thread {
public YieldThread(String name) {
super(name);
}
public synchronized void run() {
for (int i = 0; i < 5; i++) {
System.out.println(String.format("%s [%d] ---> %d", this.getName(), this.getPriority(), i));
//当i为2时调用当前线程的yield函数
if (i == 2) {
Thread.yield();
}
}
}
} public static void main(String[] args) {
ThreadFunTest.yieldDemo();
}

执行结果:

通常情况下t1首先执行,让t1的run函数执行到i等于2时让出当前线程的执行时间,因此,我们看到执行到的thread-2  等于2之前交替执行,等于2时,thread-2让出执行时间,执行thread-1,thread-1执行到2时又将执行权让出,执行thread-2直到完毕再开始执行thread-1.

调用yield就是让出当前线程的执行权,这样一来就王其他线程得到优先执行。

【java线程】的wait、sleep、join、yied的更多相关文章

  1. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  2. Java线程与多线程教程

    本文由 ImportNew - liken 翻译自 Journaldev.   Java线程是执行某些任务的轻量级进程.Java通过Thread类提供多线程支持,应用可以创建并发执行的多个线程. 应用 ...

  3. Java线程小刀牛试

    线程简介 什么是线程 现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器.堆栈和局部变量等属性,并且 ...

  4. java 笔记(5) —— 线程,yield,join

    一.线程各个状态与转换: 新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 .就绪状态:当一个线程创建了以后,其他的线程调用了它的start() ...

  5. Java线程状态及 wait、sleep、join、interrupt、yield等的区别

    Java中的线程状态(详见Java线程状态及转换-MarchOn): wait:Object类的实例方法,释放CPU执行权,进入等待状态,直到  被中断.被拥有该对象锁的线程唤醒(notify或not ...

  6. java线程join方法使用方法简介

    本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的 如图所示代码,是并行执行的 public class ThreadTest { ...

  7. (Java多线程系列六)join()的用法和线程的优先级

    join()的用法和线程的优先级 1.join()的用法 join()作用就是让其他线程处于等待状态 先看一个需求:创建一个线程,子线程执行完毕后,主线程才能执行 public class JoinT ...

  8. java 多线程 Thread.join子线程结束父线程再运行;join(long):等待超时毫秒数

    Join的使用 目的:当子线程运行结束后,父线程才能再继续运行 /** * @ClassName ThreadJoinExample * @projectName: object1 * @author ...

  9. Java线程的概念

    1.      计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...

  10. 【转载】 Java线程面试题 Top 50

    Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...

随机推荐

  1. 五分钟学会centos配置gitlab

    下载gitlab 亲测: centos6.5 安装依赖包: : yum install curl policycoreutils policycoreutils-python openssh-serv ...

  2. C#之Redis为所欲为

    一 Redis是一种支持多种数据结构的键值对数据库 1.1Redis下载地址 :https://github.com/MicrosoftArchive/Redis 建议下载 .msi结尾的应用程序进行 ...

  3. 学习Layui 第一天

    Layui 官网说这是款经典模块化前端框架 个人觉得Layui很好用,容易上手. 在学习Layui的之前.先去官网下载必要的文件 将这些文件放入项目当中 然后可以到官网看一下示例. 可以做一个简单的表 ...

  4. MySQL常见备份方案

    MySQL常见备份方案有以下三种: mysqldump + binlog lvm + binlog xtrabackup 本例为方便演示,数据库里面数据为空.下面开始动手 mkdir /opt/bac ...

  5. 【转】js 好的程序设计,应该什么时候使用 try catch 呢?

    比如在检测浏览器是否支持某些功能的时候 if (!xx) { console.error('此浏览器不支持 xx 功能') } 还是 try { xx; } catch(e) { throw new ...

  6. java的Calendar,获取月份少一月的问题及其它注意事项

    java的Calendar,获取月份少一月的问题及其它注意事项: import java.util.*; public class DateClass{ public static void main ...

  7. 聊聊 Spring Boot 2.x 那些事儿

    本文目录: 即将的 Spring 2.0 - Spring 2.0 是什么 - 开发环境和 IDE - 使用 Spring Initializr 快速入门 Starter 组件 - Web:REST ...

  8. 基于Spring Cloud、JWT 的微服务权限系统设计

    基于Spring Cloud.JWT 的微服务权限系统设计 https://gitee.com/log4j/pig https://github.com/kioyong/spring-cloud-de ...

  9. spring boot -Properties & configuration

    72. Properties & configuration72.1 Automatically expand properties at build timeRather than hard ...

  10. 利用java反射机制实现读取excel表格中的数据

    如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来. 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List<User>.Lis ...