? ? 1、線程休眠
? ? (1)sleep()
? ?
? ? ? ? 如果需要讓當前正在執(zhí)行的線程暫停一段時間,并進入阻塞狀態(tài)(Timed_Waiting),則可以通過調(diào)用Thread類的靜態(tài)sleep()方法來實現(xiàn)。
? ?
? ? ? ? static void sleep(long millis):讓當前正在執(zhí)行的線程暫停millis毫秒,并進入阻塞狀態(tài),該方法受到系統(tǒng)計時器和線程調(diào)度器的精度與準確度的影響。
? ? ? ? static void sleep(long millis,int nanos):讓當前正在執(zhí)行的線程暫停millis毫秒加nanos毫微秒,并進入阻塞狀態(tài),該方法受到系統(tǒng)計時器和線程調(diào)度器的精度與準確度的影響。
? ? ? ? 當前線程調(diào)用 sleep()方法進入阻塞狀態(tài)后,在其睡眠時間段內(nèi),該線程不會獲得執(zhí)行的機會,即使系統(tǒng)中沒有其他可執(zhí)行的線程,處于sleep()中的線程也不會執(zhí)行,因此sleep()方法常用來暫停程序的執(zhí)行。
/**
?* sleep()方法練習
? ?*/
? ?public class SleepDemo1 {
? ?public static void main(String[] args) {
? ? ? ?Thread t1 = new Thread(()->{
? ? ? ? ? while(true){
? ? ? ? ? ? ? ?System.out.println(true);
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?Thread.sleep(3000);
? ? ? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ? ? ?}
? ? ? ? ? }
? ? ? ?});
? ? ? ?//t1不調(diào)用start()方法 只調(diào)用run()方法時
? ? ? ?//此時只有main線程運行 調(diào)用sleep()休眠的是mian線程
? ? ? ?t1.run();
? ? ? ?System.out.println("main線程休眠");
? ?}文章來源:http://www.zghlxwxcb.cn/news/detail-780441.html
? ?}
/**
?* sleep()方法練習
? ?*/
? ?public class SleepDemo2 {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?Thread t2 = new Thread(()->{
? ? ? ? ? ?while(true){
? ? ? ? ? ? ? ?System.out.println(true);
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?//t2線程休眠 無法在休眠時間段內(nèi)喚醒線程
? ? ? ? ? ? ? ? ? ?Thread.sleep(1000);
? ? ? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?});
? ? ? ?t2.start();
? ? ? ?//休眠主線程 確保t2線程執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?//sleep()休眠后 t2線程的狀態(tài)為TIME_WAITING
? ? ? ?System.out.println(t2.getState());//TIMED_WAITING
? ?}
? ?}
/**
?* sleep()方法練習
? ?*/
? ?public class SleepDemo3 {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?Thread t3 = new Thread(()->{
? ? ? ? ? ?while(true){
? ? ? ? ? ? ? ?System.out.println(true);
? ? ? ? ? ?}
? ? ? ?});
? ? ? ?t3.start();
? ? ? ?//注意 sleep()是類方法 能使用創(chuàng)建對象的方式調(diào)用,但是不會有休眠效果,所以不能使用這種方式調(diào)用sleep()方法
? ? ? ?t3.sleep(1000);
? ? ? ?//休眠主線程 確保t2線程執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?//此時,t2線程不會被休眠
? ?}
? ?}
/**
?* Interrupt()方法
? ?*/
? ?public class InterruptedDemo {
? ?public static void main(String[] args) {
? ? ? ?Thread t4 = new Thread(()->{
? ? ? ? ? ?while (true){
? ? ? ? ? ? ? ?System.out.println(true);
? ? ? ? ? ?}
? ? ? ?});
? ? ? ?t4.start();
? ? ? ?//調(diào)用interrupt()方法無法中斷線程
? ? ? ?//只能采用先標記線程中斷
? ? ? ?//然后通過Thread.interrupted();判斷線程狀態(tài)是否為中斷狀態(tài)
? ? ? ?//若為true則通過拋異常的方式中斷程序
? ? ? ?t4.interrupt();
? ?}
? ?}
? ?(2) LockSupport類
? ?
? ? LockSupport是JUC提供的一個線程阻塞與喚醒的工具類,該工具類可以讓線程在任意位置阻塞和喚醒,其所有的方法都是靜態(tài)方法。
/**
?* park()方法練習
? ?*/
? ?public class LockSupportDemo1 {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?Thread t1 = new Thread(()->{
? ? ? ? ? ?System.out.println("t1線程開始休眠");
? ? ? ? ? ?//無休止休眠 t1線程為阻塞態(tài) 為Waiting
? ? ? ? ? ?LockSupport.park();
? ? ? ? ? ?System.out.println("t1線程結(jié)束休眠");
? ? ? ?});
? ? ? ?//啟動線程t1
? ? ? ?t1.start();
? ? ? ?//休眠主線程,讓線程t1能順利執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?System.out.println(t1.getState());//Waiting
? ?}
? ?}
/**
?* unpark()方法練習
? ?*/
? ?public class LockSupportDemo2 {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?Thread t2 = new Thread(()->{
? ? ? ? ? ?System.out.println("t1線程開始休眠");
? ? ? ? ? ?//休眠指定的時間 休眠后可以在休眠時間段內(nèi)重新被喚醒 比較靈活
? ? ? ? ? ?LockSupport.parkNanos(10000000000L);
? ? ? ? ? ?System.out.println("t1線程結(jié)束休眠");
? ? ? ?});
? ? ? ?//啟動線程t2
? ? ? ?t2.start();
? ? ? ?//休眠主線程,讓線程t2能順利執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?LockSupport.unpark(t2);
? ? ? ?System.out.println(t2.getState());//Time_Waiting(不定)
? ? ? ?System.out.println("線程被喚醒");
? ? ? ?System.out.println(t2.getState());//TERMINATED
? ?}
? ?}
? ?當調(diào)用park()方法時,會讓線程進入WAITING狀態(tài),調(diào)用parkNanos(long nanos)方法時,線程會進入TIMED_WAITING狀態(tài)
/**
?* unpark()方法練習
? ?*/
? ?public class LockSupportDemo2 {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?Thread t2 = new Thread(()->{
? ? ? ? ? ?System.out.println("t1線程開始休眠");
? ? ? ? ? ?//休眠指定的時間 休眠后可以在休眠時間段內(nèi)重新被喚醒 比較靈活
? ? ? ? ? ?LockSupport.parkNanos(10000000000L);
? ? ? ? ? ?System.out.println("t1線程結(jié)束休眠");
? ? ? ?});
? ? ? ?//啟動線程t2
? ? ? ?t2.start();
? ? ? ?//休眠主線程,讓線程t2能順利執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?LockSupport.unpark(t2);
? ? ? ?System.out.println(t2.getState());//Time_Waiting(不定)
? ? ? ?System.out.println("線程被喚醒");
? ? ? ?System.out.println(t2.getState());//TERMINATED
? ?}
? ?}
? ?LockSupport.park()和Thread.sleep()的區(qū)別:
? ?1、Thread.sleep()無法從外部喚醒。只能自己醒過來;而被LockSupport.park()方法阻塞的線程可以通過調(diào)用LockSupport.unpark()方法去喚醒。
? ?2、被Thread.sleep()、LockSupport.park()方法所阻塞的線程有一個特點,當被阻塞線程的Thread.interrupt()方法調(diào)用時,被阻塞線程的中斷標志將被設置,該線程將被喚醒。不同的是,二者對中斷信號的響應方式不同:LockSuppport.park()方式不會拋出InterruptedExcepton異常,僅僅設置了線程的中斷標志;而Thread.sleep()方法會拋出InterruptedException異常
? ?3、與Thread.sleep()相比,調(diào)用LockSupport.park()更能精準、更加靈活地阻塞、喚醒指定線程。
? ?2、線程讓步
? ?yield()方法是一個和 sleep()方法有點相似的方法,它也是 Thread 類提供的一個靜態(tài)方法,它也可以讓當前正在執(zhí)行的線程暫停,但它不會阻塞該線程,它只是將該線程轉(zhuǎn)入就緒狀態(tài)。
? ?yield()只是讓當前線程暫停一下,讓系統(tǒng)的線程調(diào)度器重新調(diào)度一次,線程調(diào)度器會從線程就緒隊列里獲取一個線程優(yōu)先級高的線程,當然完全可能的情況是:當某個線程調(diào)用了yield()方法暫停之后,線程調(diào)度器又將其調(diào)度出來重新執(zhí)行。
? ?當某個線程調(diào)用了yield()方法暫停之后,只有優(yōu)先級與當前線程相同,或者優(yōu)先級比當前線程更高的處于就緒狀態(tài)的線程才會獲得執(zhí)行的機會。下面程序使用yield()方法來讓當前正在執(zhí)行的線程暫停。
/**
?* yield()方法練習
? ?*/
? ?public class YieldDemo {
? ?public static void main(String[] args) {
? ? ? ?Thread t1 = new Thread(()->{
? ? ? ? ? ?for (int i = 1; i < 30; i++) {
? ? ? ? ? ? ? ?System.out.println(Thread.currentThread().getName()+"=============="+i);
? ? ? ? ? ? ? ?if(i%10==0){
? ? ? ? ? ? ? ? ? ?//調(diào)用yield方法讓t1線程暫停
? ? ? ? ? ? ? ? ? ?Thread.yield();
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?},"t1");
? ? ? ?Thread t2 = new Thread(()->{
? ? ? ? ? ?for (int i = 0; i < 30; i++) {
? ? ? ? ? ? ? ?System.out.println(Thread.currentThread().getName()+">>>"+i);
? ? ? ? ? ?}
? ? ? ?},"t2");
? ? ? ?//yield之后,有可能原來執(zhí)行的線程繼續(xù)獲得執(zhí)行的機會
? ? ? ?//為t1線程設置優(yōu)先級
? ? ? ?t1.setPriority(10);
? ? ? ?//啟動t1線程
? ? ? ?t1.start();
? ? ? ?//為t2線程設置優(yōu)先級
? ? ? ?t2.setPriority(1);
? ? ? ?//啟動t2線程
? ? ? ?t2.start();
? ? ? ?//優(yōu)先級大的線程不一定先執(zhí)行,而是執(zhí)行概率大
? ? ? ?for (int i = 0; i < 30; i++) {
? ? ? ? ? ?System.out.println(Thread.currentThread().getName()+">>>"+i);
? ? ? ?}
? ?}
? ?}
? ?3、線程優(yōu)先級
? ?每個線程執(zhí)行時都具有一定的優(yōu)先級,優(yōu)先級高的線程獲得較多的執(zhí)行機會,而優(yōu)先級低的線程則獲得較少的執(zhí)行機會。每個線程默認的優(yōu)先級都與創(chuàng)建它的父線程的優(yōu)先級相同,在默認情況下,main線程具有普通優(yōu)先級,由main線程創(chuàng)建的子線程也具有普通優(yōu)先級。
? ?Thread類提供了setPriority(int newPriority)、getPriority()方法來設置和返回指定線程的優(yōu)先級,其中setPriority()方法的參數(shù)可以是一個整數(shù),范圍是1~10之間,也可以使用Thread類的如下3個靜態(tài)常量。
? ?MAX_PRIORITY:其值是10。
? ?MIN_PRIORITY:其值是1。
? ?NORM_PRIORITY:其值是5。
/**
?* 優(yōu)先級練習
? ?*/
? ?public class PriorityDemo {
? ?public static void main(String[] args) throws InterruptedException {
? ? ? ?//定義存放線程的數(shù)組
? ? ? ?MyThread[] myThreads = new MyThread[10];
? ? ? ?int length = myThreads.length;
? ? ? ?//優(yōu)先級為1<-->10 循環(huán)需要從1開始
? ? ? ?for (int i = 1; i <=length; i++) {
? ? ? ? ? ?//創(chuàng)建線程
? ? ? ? ? ?myThreads[i-1] = new MyThread();
? ? ? ? ? ?//分別創(chuàng)建線程優(yōu)先級
? ? ? ? ? ?myThreads[i-1].setPriority(i);
? ? ? ? ? ?//啟動線程
? ? ? ? ? ?myThreads[i-1].start();
? ? ? ?}
? ? ? ?//休眠主線程 讓創(chuàng)建的線程得以執(zhí)行
? ? ? ?TimeUnit.SECONDS.sleep(3);
? ? ? ?for (int i = 0; i < length; i++) {
? ? ? ? ? ?//停止線程
? ? ? ? ? ?myThreads[i].stop();
? ? ? ?}
? ?}
? ?}
? ?優(yōu)先級的繼承
? ?/**
?* 優(yōu)先級練習2
? ?*/
? ?public class PriorityDemo2 {
? ?public static void main(String[] args) {
? ? ? ?Thread thread = new Thread(()->{
? ? ? ? ? ?System.out.println("線程thread執(zhí)行");
? ? ? ?},"thread");
? ? ? ?Thread main = Thread.currentThread();
? ? ? ?System.out.println(main.getState());
? ? ? ?System.out.println(main.getName()+"線程的優(yōu)先級:"+main.getPriority());
? ? ? ?//在main線程中創(chuàng)建thread線程,thread線程的優(yōu)先級與main線程一致
? ? ? ?thread.start();
? ? ? ?System.out.println(thread.getName()+"線程的優(yōu)先級:"+thread.getPriority());
? ?}
? ?}
?文章來源地址http://www.zghlxwxcb.cn/news/detail-780441.html
到了這里,關于線程休眠、線程讓步、線程優(yōu)先級相關內(nèi)容學習筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!