Java中的線程狀態轉換和線程控制常用方法


Java 中的線程狀態轉換:

  

【注】:不是 start 之后就立刻開始執行, 只是就緒了(CPU 可能正在運行其他的線程).

【注】:只有被 CPU 調度之后,線程才開始執行, 當 CPU 分配給你的時間片到了, 又回到就緒狀態, 繼續排隊等候.

線程控制的基本方法:

  isAlive(): 判斷線程是否還活着, start 之后,終止之前都是活的;

  getPriority(): 獲得線程的優先級數值;

  setPriority(): 設置線程的優先級數值(線程室友優先級別的);

    Thread.sleep(): 將當前線程睡眠指定毫秒數;

  join(): 調用某線程的該方法, 將當前線程與該線程合並, 也即等待該線程結束后, 再恢復當前線程的運行狀態(比如在線程B中調用了線程A的 join() 方法,直到線程A執行完畢后,才會繼續執行線程B);

  yield(): 當前線程讓出 CPU, 進入就緒狀態, 等待 CPU 的再次調度;

  wait(): 當前線程進入對象的 wait pool;

  notify()/notifyAll(): 喚醒對象的 wait pool 中的一個/所有的等待線程.

1. sleep()方法:

  ① 可以調用 Thread 的靜態方法:

    public static void sleep(long millis) throws InterruptedException:在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度程序精度和准確性的影響, 該線程不丟失任何監視器的所屬權.

    InterruptedException - 如果任何線程中斷了當前線程。當拋出該異常時,當前線程的中斷狀態 被清除

  ② 由於是靜態方法, sleep() 可以由類名直接調用.

    Thread.sleep(.....);

  Demo_1:

import java.util.*;
class TestThread {
	public static void main(String[] args) {
		MyThread thread = new MyThread();
		thread.start();
		try {                    // 在哪個線程中調用 Sleep,就讓哪個線程睡眠
			Thread.sleep(8000); // 主線程睡8秒后,打斷子線程
		} catch (InterruptedException e) {
		}
		thread.interrupt(); // 打斷子線程
	}
}
class MyThread extends Thread {
	@Override
	public void run() {
		while(true){
			System.out.println("=== "+ new Date()+" ===");
			try {
				sleep(1000); // 每隔一秒打印一次日期
			} catch (InterruptedException e) {
				return;
			}
		}
	}	
}

 運行結果:

=== Tue May 09 11:09:43 CST 2017 ===
=== Tue May 09 11:09:44 CST 2017 ===
=== Tue May 09 11:09:45 CST 2017 ===
=== Tue May 09 11:09:46 CST 2017 ===
=== Tue May 09 11:09:47 CST 2017 ===
=== Tue May 09 11:09:48 CST 2017 ===
=== Tue May 09 11:09:49 CST 2017 ===
=== Tue May 09 11:09:50 CST 2017 ===

子線程每隔一秒打印系統日期, 主線程睡眠8秒后,打斷子線程,子線程結束.

  Demo_2: 在本例中,采用一種簡單、粗暴、好用的方法中斷子線程

import java.util.*;
class TestThread {
	public static void main(String[] args) {
		MyThread thread = new MyThread();
		thread.start();
		try {                    // 在哪個線程中調用 Sleep,就讓哪個線程睡眠
			Thread.sleep(5000); // 主線程睡8秒后,打斷子線程
		} catch (InterruptedException e) {
		}
		thread.flag = false; // 打斷子線程
	}
}
class MyThread extends Thread {
	boolean  flag = true;
	@Override
	public void run() {
		while(flag){
			System.out.println("=== "+ new Date()+" ===");
			try {
				sleep(1000); // 每隔一秒打印一次日期
			} catch (InterruptedException e) {
			}
		}
	}
}

 運行結果:

=== Tue May 09 12:21:24 CST 2017 ===
=== Tue May 09 12:21:25 CST 2017 ===
=== Tue May 09 12:21:26 CST 2017 ===
=== Tue May 09 12:21:27 CST 2017 ===
=== Tue May 09 12:21:28 CST 2017 ===

2. join()方法:

  合並某個線程, 相當於方法的調用

  Demo_3:

class TestThread {
	public static void main(String[] args) {
		MyThread myThread = new MyThread("childThread");
		myThread.start();
		try {
			myThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		for(int i = 1; i <= 4; i++){
			System.out.println("I am the mainThread");
		}
	}
}
class MyThread extends Thread {
	public MyThread(String name) {
		super(name);
	}
	@Override
	public void run() {
		for(int i = 1; i <= 4; i++){
			System.out.println("I am " + getName());
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}
}

 運行結果:

I am childThread
I am childThread
I am childThread
I am childThread
I am the mainThread
I am the mainThread
I am the mainThread
I am the mainThread

等待線程結束后, 再恢復當前線程的運行.

3. yield()方法:

  讓出 CPU , 當前線程進入就緒狀態隊列等待, 給其他線程執行的機會(就讓很小的一個時間片段).

Demo_4:

class TestThread {
	public static void main(String[] args) {
		MyThread my1 = new MyThread("t1");
		MyThread my2 = new MyThread("t2");
		my1.start();
		my2.start();
	}
}
class MyThread extends Thread {
	public MyThread(String s) {
		super(s);
	}
	@Override
	public void run() {
		for(int i = 1; i <= 100; i++){
			System.out.println(getName()+":"+i);
			if(i % 10 == 0) {
				Thread.yield(); // 當前線程讓出 CPU 一小會
			}
		}
	}	
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM