在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關鍵字相关推荐

  1. java中speak方法的意思_Java中的關鍵字

    首先是訪問控制的關鍵字,分 public.protected.default.private四種,權限如下: (權限)      public      protected     default   ...

  2. java 原子性加法_Java多線程之原子性 volatile、atomicInteger測試

    一.補充概念 1.什么是線程安全性? <Java Concurrency in Practice>中有提到:當多個線程訪問某個類時,這個類始終都能表現出正確的行為,那么就稱這個類是線程安全 ...

  3. JAVA中的多线程(八):线程的优先级和yield方法

    JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...

  4. java匹配任意,java有关正则表示式,我想匹配一个字串中的任意字元,怎么办?...

    java有关正则表示式,我想匹配一个字串中的任意字元,怎么办?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! java有 ...

  5. 基于Java的超市管理系统源码,数据库MySQL(附加论文13000字)

    目录 1.摘要 2.社会背景 3.系统可行性研究 4.系统的功能结构(图) 5.功能需求 6.开发环境介绍 7.系统数据流(图) 8.数据库(E-R模型) 9.功能展示 10.论文目录结构 11.源码 ...

  6. Java中获取GBK编码汉字的拼音首字母(包括生僻字)

    Java中获取GBK编码汉字的拼音首字母(包括生僻字) 前言 代码 结果 前言 网上关于Java中获取汉字的拼音首字母的方法很多,但大多基于GB2312的汉字所属编码位置判断方法,现有一种基于GBK编 ...

  7. java suspend() 和 resume(),java多線程之(suspend()、resume())

    suspend()和resume()方法,從字面意義上可以了解到這兩個方法是一對的,suspend()方法就是將一個線程掛起(暫停),resume()方法就是將一個掛起線程復活繼續執行.參照例子: p ...

  8. java jni helloword_JNI入门教程之HelloWorld篇

    JNI入门教程之HelloWorld篇 来源:互联网  宽屏版  评论 2008-05-31 09:07:11 本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第 ...

  9. java 时间戳_Java并发编程之CAS三CAS的缺点 及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

最新文章

  1. Core-3399-JD4 六核高性能AI核心板
  2. Linux中的基础IO(一)
  3. SPOJ_SUBLEX
  4. 如何使用SAP Analytics Cloud统计C4C系统每天新建的Lead个数和预测趋势
  5. 中国房地产市值已经超过450万亿,为何还不见房价下跌?
  6. 【牛客 - 369C】小A与欧拉路(bfs树的直径)
  7. python 多进程 每个进程做不同功能实例_Python 多进程并发操作中进程池Pool的实例...
  8. echarts标记线的样式_ECharts提示框组件指示器的线条样式
  9. 第一个cocos2d-x 项目
  10. Wait-for-it之参考
  11. 法国政府正考虑采用开源软件
  12. Qt + OpenSenceGraph(osg) 加载OSG模型
  13. mysql数据库一般多大_数据库一般多大
  14. 云计算的核心技术有哪些?
  15. 软考分类精讲-软件管理
  16. 大容量sd卡reread之后/dev下概率性出现无设备文件
  17. 安装谷歌扩展插件:程序包无效
  18. 互联网日报 | 1月19日 星期二 | 腾讯音乐全资收购懒人听书;字节跳动整合硬件业务专注教育硬件;PSA与FCA正式完成合并...
  19. Ubuntu桌面出现Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to vi等三行错误时
  20. java 三元运算符

热门文章

  1. python循环实验心得_2019.06.18学习python循环总结
  2. 计算机丢失wininet,win7系统启动程序提示因为计算机中丢失wininet.dll的解决方法...
  3. python 等值线 标注 间距、控制_python - Matplotlib-Contourf-如何使刻度线间距不均匀? - 堆栈内存溢出...
  4. python3spark文本分类_如何用Spark深度集成Tensorflow实现文本分类?
  5. vue data 值如何渲染_Vue执行流程解析
  6. exit()与_exit()的区别
  7. DNS 流程说明以及相关问题的解析
  8. 这样一款超低功耗的集成 2.4 GHz Wi-Fi 和支持长距离的 Bluetooth LE 5.0的SOC,你怎么能不爱它?
  9. linux可以生成pdb调试信息吗,Linux通过使用pdb简单调试python计划
  10. tab css html,纯css的tab 切换