本文目錄一覽:
- 1、java的等待喚醒機制必須要讓線程等待嗎
- 2、java 如何實現等待子線程結束
- 3、java怎麼設置等待點擊按鈕
- 4、Java如何等待子線程執行結束
- 5、java 等待一秒方法
- 6、JAVA中如何設置等待時間(非線程)
java的等待喚醒機制必須要讓線程等待嗎
1. 線程的掛起和喚醒
掛起實際上是讓線程進入「非可執行」狀態下,在這個狀態下CPU不會分給線程時間片,進入這個狀態可以用來暫停一個線程的運行;在線程掛起後,可以通過重新喚醒線程來使之恢復運行。
掛起的原因可能是如下幾種情況:
(1)通過調用sleep()方法使線程進入休眠狀態,線程在指定時間內不會運行。
(2)通過調用join()方法使線程掛起,使自己等待另一個線程的結果,直到另一個線程執行完畢為止。
(3)通過調用wait()方法使線程掛起,直到線程得到了notify()和notifyAll()消息,線程才會進入「可執行」狀態。
(4)使用suspend掛起線程後,可以通過resume方法喚醒線程。
雖然suspend和resume可以很方便地使線程掛起和喚醒,但由於使用這兩個方法可能會造成死鎖,因此,這兩個方法被標識為deprecated(抗議)標記,這表明在以後的jdk版本中這兩個方法可能被刪除,所以盡量不要使用這兩個方法來操作線程。
調用sleep()、yield()、suspend()的時候並沒有被釋放鎖
調用wait()的時候釋放當前對象的鎖
wait()方法表示,放棄當前對資源的占有權,一直等到有線程通知,才會運行後面的代碼。
notify()方法表示,當前的線程已經放棄對資源的佔有,通知等待的線程來獲得對資源的占有權,但是只有一個線程能夠從wait狀態中恢復,然後繼續運行wait()後面的語句。
notifyAll()方法表示,當前的線程已經放棄對資源的佔有,通知所有的等待線程從wait()方法後的語句開始運行。
2.等待和鎖實現資源競爭
等待機制與鎖機制是密切關聯的,對於需要競爭的資源,首先用synchronized確保這段代碼只能一個線程執行,可以再設置一個標誌位condition判斷該資源是否準備好,如果沒有,則該線程釋放鎖,自己進入等待狀態,直到接收到notify,程序從wait處繼續向下執行。
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
以上程序表示只有一個線程A獲得了obj鎖後,發現條件condition不滿足,無法繼續下一處理,於是線程A釋放該鎖,進入wait()。
在另一線程B中,如果B更改了某些條件,使得線程A的condition條件滿足了,就可以喚醒線程A:
synchronized(obj) {
condition = true;
obj.notify();
}
需要注意的是:
# 調用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) {…} 代碼段內。
# 調用obj.wait()後,線程A就釋放了obj的鎖,否則線程B無法獲得obj鎖,也就無法在synchronized(obj) {…} 代碼段內喚醒A。
# 當obj.wait()方法返回後,線程A需要再次獲得obj鎖,才能繼續執行。
# 如果A1,A2,A3都在obj.wait(),則B調用obj.notify()只能喚醒A1,A2,A3中的一個(具體哪一個由JVM決定)。
# obj.notifyAll()則能全部喚醒A1,A2,A3,但是要繼續執行obj.wait()的下一條語句,必須獲得obj鎖,因此,A1,A2,A3隻有一個有機會獲得鎖繼續執行,例如A1,其餘的需要等待A1釋放obj鎖之後才能繼續執行。
# 當B調用obj.notify/notifyAll的時候,B正持有obj鎖,因此,A1,A2,A3雖被喚醒,但是仍無法獲得obj鎖。直到B退出synchronized塊,釋放obj鎖後,A1,A2,A3中的一個才有機會獲得鎖繼續執行。
java 如何實現等待子線程結束
有多種實現方式,下面列出兩種。
第一種:實現Callable類,使用有返回值的線程,只有線程執行完成後才會返回結果。
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
public class Main {
// 初始化一個容量為10的線程池
static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
ListFutureString futures = new ArrayList();
for (int i = 0; i 3; i++) {
MyThread thread = new MyThread(“線程” + i);
futures.add(pool.submit(thread));
}
for (FutureString future : futures) {
String name = future.get();
System.out.println(name + “執行完成…”);
}
System.out.println(“所有線程執行完成!”);
}
}
class MyThread implements CallableString {
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
// TODO 執行業務
// 隨機延遲,模擬線程耗時
Thread.sleep(1000 + new Random().nextInt(2000));
return name;
}
}
第二種:使用CountDownLatch實現線程計數,代碼如下:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main2 {
// 初始化一個容量為10的線程池
static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
// 初始化CountDownLatch,用於線程計數
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i threadCount; i++) {
MyThread thread = new MyThread(“線程” + i, latch);
pool.execute(thread);
}
// 阻塞當前線程,CountDownLatch計數減為0時表示所有線程都執行完畢,才會釋放主線程的阻塞
latch.await();
System.out.println(“所有線程執行完成!”);
}
}
class MyThread implements Runnable {
private String name;
private CountDownLatch latch;
public MyThread(String name, CountDownLatch latch) {
this.name = name;
this.latch = latch;
}
@Override
public void run() {
// TODO 執行業務
// 隨機延遲,模擬線程耗時
try {
Thread.sleep(1000 + new Random().nextInt(2000));
} catch (InterruptedException e) {
}
// 計數減一
latch.countDown();
System.out.println(name + “執行完畢…”);
}
}
java怎麼設置等待點擊按鈕
給你個簡單的思路吧,你可以定義一個boolean變數,默認是false,當點下按鈕以後,通過點擊事件這個變數的值改成true;
private isRun =false;
pubilc void method(){
while(true){
if(isRun){
//執行你的代碼
break;
}
}}
Java如何等待子線程執行結束
先調用
shutdown
在調用
isTerminated
例:
/*
* 採用線程池開啟多個子線程,主線程等待所有的子線程執行完畢
*/
public static void moreThread() {
try {
int threadNum = 0;
for (int i = 0; i 10; i++) {
threadNum++;
final int currentThreadNum = threadNum;
exe.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(“子線程[” + currentThreadNum + “]開啟”);
Thread.sleep(1000*10);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println(“子線程[” + currentThreadNum + “]結束”);
}
}
});
}
System.out.println(“已經開啟所有的子線程”);
exe.shutdown();
System.out.println(“shutdown():啟動一次順序關閉,執行以前提交的任務,但不接受新任務。”);
while(true){
if(exe.isTerminated()){
System.out.println(“所有的子線程都結束了!”);
break;
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println(“主線程結束”);
}
}
java 等待一秒方法
sleep是靜態方法,它的調用會引起所有進程的休眠。
在等待的進程中執行notify()和wait()方法,在外面的進程計時,執行夠一秒的時候放棄cpu,讓之前的線程執行
JAVA中如何設置等待時間(非線程)
java中使用用線程式控制制Task任務,啟動下面的線程就可以了,new Thread(new Task()).start() ;public class
Task implements Runnable {//新建一個任務
private TextArea textArea;
public Task(TextArea textArea){
this.textArea = textArea;
}
public void run() {
while (true) {
this.textArea.setText(“這裡設置: 輸出的一段文字”);
try {
Thread.sleep(500); // 這裡設置:隔多長時間
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/256949.html