java sleep join_Java多線程之sleep,wait,join和yield關鍵字
在java或者android中,使用Thread和Runnable就可以玩多線程了,這個成本比較低,也沒什么好說的,今天主要是針對多線程中主要的關鍵字wait,sleep,join和yield做個筆記,加強一下印象。
wait
wait方法一般都是和notity()或者notifyAll()成對出現的。當某個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去了對象的鎖功能,使得其他線程可以訪問該對象。用戶可以使用notify或者notifyAll或者指定睡眠時間來喚醒當前等待池中的線程。wait,notify和notifyAll方法都必須放在synchronized 代碼塊中,否則就會報java.lang.IllegalMonitorStateException。
下面的例子中,在主線程中會存在一個waitObject對象使用wait方法進行等待,而開啟子線程睡眠3秒之后,notifyAll該waitObject對象,使得主線程繼續執行:private static Object waitObject = new Object();
public static void main(String[] args) {
System.out.println("主線程開始運行");
WaitThread thread = new WaitThread();
thread.start();
long t1 = System.currentTimeMillis();
try{
synchronized(waitObject) {
System.out.println("主線程等待");
waitObject.wait();
System.out.println("主線程等待結束");
}
}catch(Exception e){
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
System.out.println("最終時間為:" + (t2 - t1));
}
//定義等待線程
static class WaitThread extends Thread{
@Override
public void run() {
System.out.println("進入子線程run方法");
try{
sleep(3000);
synchronized(waitObject) {
waitObject.notifyAll();
System.out.println("子線程notifyAll結束");
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
程序運行的結果為:
可見wait和notity可用於等待機制的實現,當條件不滿足時進行等待,一旦條件滿足,則notity或者notifyAll喚醒等待線程繼續執行。經典的消費者-生產者模式可以使用wait和notity進行設計。
join
等待目標線程執行完成之后再繼續執行。說的比較含糊,還是來看看例子吧。下面有兩個工作子線程,都需要進行2s的耗時才能完成任務:public static void main(String[] args) throws Exception {
Thread t1 = new WorkThread("work1");
Thread t2 = new WorkThread("work2");
t1.start();
//t1.join();
t2.start();
//t2.join();
System.out.println("當前主線程結束");
}
//工作線程
static class WorkThread extends Thread{
public WorkThread(String name){
super(name);
}
@Override
public void run() {
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("the current thread is " + getName());
}
}
首先先注釋掉join方法,直接運行,可以看到的結果如下圖:
我們可以看到,主線程首先執行完成,而后兩個子線程分別執行完成,現在我們打開我們的t1.join()和t2.join()方法,得出的結果為:
程序執行的順序是 t1->t2->main thread,相當於三個程序的串聯執行,這也就是join的作用,一旦某個線程使用了join,那么它就先執行完畢,其他線程才有機會繼續執行。
yield
線程禮讓。使用yield方法的線程將由運行狀態轉變為就緒狀態,也就是讓出執行的狀態,讓其他線程得以優先執行,但是其他線程未必一定是有限執行的。簡單通俗一點,就是線程先等着,我會讓其他線程有優先的機會去運行。下面的例子可以簡單說明問題:有兩個單獨的子線程t1,t2分別獨自運行,t1中run遍歷到4時,會執行yield方法,那么我們的猜測就是此時t1將會變回就緒狀態,不再搶奪CPU資源,等到其他線程執行完畢后,再次從就緒狀態變為運行狀態,從而完成以后的任務。代碼如下:public static void main(String[] args) {
//線程t1運行到4時 會執行yield方法
Thread t1 = new YieldClass("線程1",4);
//線程t2將一直運行下去
Thread t2 = new YieldClass("線程2",-1);
t1.start();
t2.start();
System.out.println("主線程結束");
}
static class YieldClass extends Thread{
public int mIndex ;
public YieldClass(String name ,int index) {
super(name);
this.mIndex = index;
}
@Override
public void run() {
for(int i = 0 ; i < 10 ; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
if(i == mIndex) {
yield();
}
}
}
}
我們來看運行的效果圖:
可以看到圖中,t1和t2先並行運行,可是當t1運行到4時,由於執行了yield方法,此時t1將會變為就緒狀態,t2線程會執行下去,t2線程執行完成之后,t1才會繼續執行,跟我們預想的方式是一樣的。
sleep
sleep方法是我們平常用得最多的,它是Thread的靜態函數,作用是使得調用的Thread進入休眠狀態。由於是Static修飾的方法,因此不能修改對象的鎖機制,所以當一個synchronized塊中調用了sleep方法,線程雖然休眠了,但是對象的鎖機制並沒有被釋放。其他線程將會無法訪問到這個對象。下面舉個例子:有兩個子線程,一個需要睡眠3s,另一個不需要睡眠,兩個子線程都使用了synchronized塊,我們來看看兩個線程結束之后所用的時間,代碼如下:public class TestSleep {
private static Object mLock = new Object();
public static void main(String[] args) {
Thread t1 = new SleepThread();
Thread t2 = new WordThread() ;
t1.start();
t2.start();
System.out.println("-----主線程執行完成-----"+ System.currentTimeMillis());
}
static class SleepThread extends Thread {
@Override
public void run() {
synchronized(mLock){
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("----睡眠線程執行完成-----" + System.currentTimeMillis());
}
}
}
static class WordThread extends Thread{
@Override
public void run() {
synchronized (mLock) {
System.out.println("----工作線程執行完成-----" + System.currentTimeMillis());
}
}
}
}
結果為:
我們發現了睡眠線程和工作線程幾乎都是等待了3秒之后才結束的,這就表明了sleep引用了對象鎖,其他線程將無法訪問該對象了。我們去掉synchronized代碼塊,再來看一次結果:
我們發現睡眠線程和主線程幾乎同時完成工作,只有睡眠線程睡眠3秒之后才結束工作,由於沒有引用相同的對象,線程之間不影響各自的工作,此時就不存在同步的問題了。
好了,今天基本上就說到這里了,由於以前很少了解這些東西,以致很多關於多線程方面的東西都看得不是很懂,今天算是個入門吧。
java sleep join_Java多線程之sleep,wait,join和yield關鍵字相关推荐
- java中speak方法的意思_Java中的關鍵字
首先是訪問控制的關鍵字,分 public.protected.default.private四種,權限如下: (權限) public protected default ...
- java 原子性加法_Java多線程之原子性 volatile、atomicInteger測試
一.補充概念 1.什么是線程安全性? <Java Concurrency in Practice>中有提到:當多個線程訪問某個類時,這個類始終都能表現出正確的行為,那么就稱這個類是線程安全 ...
- JAVA中的多线程(八):线程的优先级和yield方法
JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...
- java匹配任意,java有关正则表示式,我想匹配一个字串中的任意字元,怎么办?...
java有关正则表示式,我想匹配一个字串中的任意字元,怎么办?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! java有 ...
- 基于Java的超市管理系统源码,数据库MySQL(附加论文13000字)
目录 1.摘要 2.社会背景 3.系统可行性研究 4.系统的功能结构(图) 5.功能需求 6.开发环境介绍 7.系统数据流(图) 8.数据库(E-R模型) 9.功能展示 10.论文目录结构 11.源码 ...
- Java中获取GBK编码汉字的拼音首字母(包括生僻字)
Java中获取GBK编码汉字的拼音首字母(包括生僻字) 前言 代码 结果 前言 网上关于Java中获取汉字的拼音首字母的方法很多,但大多基于GB2312的汉字所属编码位置判断方法,现有一种基于GBK编 ...
- java suspend() 和 resume(),java多線程之(suspend()、resume())
suspend()和resume()方法,從字面意義上可以了解到這兩個方法是一對的,suspend()方法就是將一個線程掛起(暫停),resume()方法就是將一個掛起線程復活繼續執行.參照例子: p ...
- java jni helloword_JNI入门教程之HelloWorld篇
JNI入门教程之HelloWorld篇 来源:互联网 宽屏版 评论 2008-05-31 09:07:11 本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第 ...
- java 时间戳_Java并发编程之CAS三CAS的缺点 及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
最新文章
- Core-3399-JD4 六核高性能AI核心板
- Linux中的基础IO(一)
- SPOJ_SUBLEX
- 如何使用SAP Analytics Cloud统计C4C系统每天新建的Lead个数和预测趋势
- 中国房地产市值已经超过450万亿,为何还不见房价下跌?
- 【牛客 - 369C】小A与欧拉路(bfs树的直径)
- python 多进程 每个进程做不同功能实例_Python 多进程并发操作中进程池Pool的实例...
- echarts标记线的样式_ECharts提示框组件指示器的线条样式
- 第一个cocos2d-x 项目
- Wait-for-it之参考
- 法国政府正考虑采用开源软件
- Qt + OpenSenceGraph(osg) 加载OSG模型
- mysql数据库一般多大_数据库一般多大
- 云计算的核心技术有哪些?
- 软考分类精讲-软件管理
- 大容量sd卡reread之后/dev下概率性出现无设备文件
- 安装谷歌扩展插件:程序包无效
- 互联网日报 | 1月19日 星期二 | 腾讯音乐全资收购懒人听书;字节跳动整合硬件业务专注教育硬件;PSA与FCA正式完成合并...
- Ubuntu桌面出现Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to vi等三行错误时
- java 三元运算符
热门文章
- python循环实验心得_2019.06.18学习python循环总结
- 计算机丢失wininet,win7系统启动程序提示因为计算机中丢失wininet.dll的解决方法...
- python 等值线 标注 间距、控制_python - Matplotlib-Contourf-如何使刻度线间距不均匀? - 堆栈内存溢出...
- python3spark文本分类_如何用Spark深度集成Tensorflow实现文本分类?
- vue data 值如何渲染_Vue执行流程解析
- exit()与_exit()的区别
- DNS 流程说明以及相关问题的解析
- 这样一款超低功耗的集成 2.4 GHz Wi-Fi 和支持长距离的 Bluetooth LE 5.0的SOC,你怎么能不爱它?
- linux可以生成pdb调试信息吗,Linux通过使用pdb简单调试python计划
- tab css html,纯css的tab 切换