勿以惡小而爲之,勿以善小而不爲--------------------------劉備
勸諸君,多行善事積福報,莫作惡
上一章簡單介紹了 Thread和Runnable實現多線程(一),如果沒有看過,請觀看上一章
一. Thread 的靜態優先級常量
一.一 靜態常量
靜態常量 | 值 |
---|---|
MAX_PRIORITY | 最大優先級,值爲10 |
MIN_PRIORITY | 最小優先級,值爲1 |
NORM_PRIORITY | 默認優先級,值爲5 |
一. 二 演示 優先級常量
@Test
public void staticTest(){
System.out.println("max:"+Thread.MAX_PRIORITY);
System.out.println("norm:"+Thread.NORM_PRIORITY);
System.out.println("min:"+Thread.MIN_PRIORITY);
}
運行測試,查看控制檯:
二. Thread 中方法
二.一 構造 方法
二.一.一 方法
方法 | 作用 |
---|---|
Thread() | 默認,線程的名稱系統自定義 |
Thread(String name) | 用戶傳入唯一的線程名稱 |
Thread(Runnable target) | 傳入 runnable對象 |
Thread(Runnable target, String name) | 傳入runnable對象和唯一線程名稱name |
二.一.二 演示構造方法
@Test
public void conTest(){
//空構造
Thread thread=new Thread();
//傳入名稱
Thread thread1=new Thread("自定義線程");
//傳入Runnable
Thread thread2=new Thread(new MyRunnable());
//4 傳入Runnable 和name
Thread thread3=new Thread(new MyRunnable(),"自定義Runnable接口");
}
二.二 其他方法
方法 | 作用 |
---|---|
static Thread currentThread() | 獲取當前的運行線程 |
void setName(String name) | 設置線程的名稱,一般在線程運行之前設置 |
String getName() | 獲取線程的名稱 |
void setPriority(int newPriority) | 設置線程的優先級 |
int getPriority() | 獲取線程的優先級 |
Thread.State getState() | 獲取線程的狀態 |
boolean isAlive() | 判斷線程是否還活着 |
void setDaemon(boolean on) | 設置是否是守護線程,必須在未start 之前設置 |
boolean isDaemon() | 是否是守護線程 |
void interrupt() | 中斷線程 |
static boolean interrupted() | 線程是否已經中斷 |
boolean isInterrupted() | 是否被中斷 |
void join() | 讓此線程獲取資源,強制運行 |
static void sleep(long millis) | 優眠, 單位是毫秒 |
void start() | 開啓 |
static void yield() | 線程釋放資源,不首先運行 |
三. 演示線程名稱 getName()
@Test
public void nameTest() throws Exception{
NameThread nameThread=new NameThread();
Thread thread1=new Thread(nameThread);
//默認的爲 Thread-接下來的數據, 從0開始。
Thread thread2=new Thread(nameThread,"自定義線程");
Thread thread3=new Thread(nameThread);
Thread thread4=new Thread(nameThread,"兩個蝴蝶飛,你好");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
// main, main方法也是一個線程
System.out.println("當前線程的名稱:"+Thread.currentThread().getName());
}
class NameThread implements Runnable{
@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println("當前線程:"+Thread.currentThread().getName()+"正在運行,輸出:"+i);
}
}
}
運行程序,控制檯打印輸出
如果不傳入線程的名稱, 則線程的名稱系統自分配爲: Thread-不重複數字
四. 獲取線程的信息
四.一 主線程狀態
@Test
public void readMainTest() throws Exception{
//1. 獲取當前的主線程
Thread thread=Thread.currentThread();
System.out.println("當前線程的名稱:"+thread.getName());
System.out.println("獲取標識符 id:"+thread.getId());
System.out.println("獲取優先級:"+thread.getPriority());
System.out.println("獲取狀態:"+thread.getState());
System.out.println("當前線程是否還活着:"+thread.isAlive());
System.out.println("是否被中斷:"+thread.isInterrupted());
System.out.println("是否是守護線程:"+thread.isDaemon());
//可以手動設置名稱和優先級
thread.setName("手動設置名稱");
thread.setPriority(Thread.MAX_PRIORITY);
System.out.println("當前線程的名稱:"+thread.getName());
System.out.println("獲取優先級:"+thread.getPriority());
//設置守護線程,必須要在線程運行之前進行設置
}
運行程序,看控制檯輸出:
四.二 Runnable 線程狀態
@Test
public void readNoTest() throws Exception{
ReadRunnable readRunnable=new ReadRunnable();
Thread thread=new Thread(readRunnable);
thread.start();
}
class ReadRunnable implements Runnable{
@Override
public void run() {
Thread thread=Thread.currentThread();
System.out.println("當前線程的名稱:"+thread.getName());
System.out.println("獲取標識符 id:"+thread.getId());
System.out.println("獲取優先級:"+thread.getPriority());
System.out.println("獲取狀態:"+thread.getState());
System.out.println("當前線程是否還活着:"+thread.isAlive());
System.out.println("是否被中斷:"+thread.isInterrupted());
System.out.println("是否是守護線程:"+thread.isDaemon());
//可以手動設置名稱和優先級
thread.setName("手動設置名稱");
thread.setPriority(Thread.MAX_PRIORITY);
System.out.println("當前線程的名稱:"+thread.getName());
System.out.println("獲取優先級:"+thread.getPriority());
}
}
運行程序,控制檯打印輸出:
五. 守護線程 setDaemon()
守護線程指的就是, 即使 Main 線程結束了, 此線程仍然會繼續運行。
五.一 設置守護線程
@Test
public void read3Test() throws Exception{
Read3Runnable readRunnable=new Read3Runnable();
Thread thread=new Thread(readRunnable);
System.out.println("判斷是否啓動:"+thread.isAlive());
System.out.println("是否是守護線程:"+thread.isDaemon());
//在開啓之前設置
thread.setDaemon(true);
thread.start();
System.out.println("是否啓動:"+thread.isAlive());
System.out.println("是否是守護線程:"+thread.isDaemon());
}
class Read3Runnable implements Runnable{
@Override
public void run() {
System.out.println("獲取線程的名稱:"+Thread.currentThread().getName());
}
}
運行程序,控制檯打印輸出:
五.二 守護線程
@Test
public void daemonTest() throws Exception{
DaemonRunnable daemonRunnable=new DaemonRunnable();
Thread thread=new Thread(daemonRunnable);
//先不是守護線程
//啓動
// thread.setDaemon(true);
thread.start();
}
static class DaemonRunnable implements Runnable{
@Override
public void run() {
//死循環,會一直執行。
for(;;){
System.out.println("我扣");
}
}
}
此時運行, ,則運行一段時間之後,結束運行
如果將註釋去掉,設置成守護線程的話,則會一直打印輸出。
六. 線程的狀態 State
線程的狀態有以下幾種:
- NEW 尚未啓動的線程處於此狀態。
- RUNNABLE 在Java虛擬機中執行的線程處於此狀態。
- BLOCKED 被阻塞等待監視器鎖定的線程處於此狀態。
- WAITING 正在等待另一個線程執行特定動作的線程處於此狀態。
- TIMED_WAITING 正在等待另一個線程執行動作達到指定等待時間的線程處於此狀態。
- TERMINATED 已退出的線程處於此狀態。
@Test
public void readStateTest() throws Exception{
ReadStateRunnable readRunnable=new ReadStateRunnable();
Thread thread=new Thread(readRunnable);
Thread.State state=thread.getState();
System.out.println("開啓前狀態:"+state);
thread.start();
state=thread.getState();
System.out.println("開啓後狀態:"+state);
}
class ReadStateRunnable implements Runnable{
@Override
public void run() {
System.out.println("獲取線程的名稱:"+Thread.currentThread().getName());
}
}
運行程序,控制檯打印輸出:
七. 線程優眠 sleep
會暫停時間。
//線程的休眠
@Test
public void sleepTest(){
SleepRunnable readRunnable=new SleepRunnable();
Thread thread=new Thread(readRunnable);
thread.start();
//休眠5秒, 保證後面的先不執行。
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠結束,運行成功");
}
class SleepRunnable implements Runnable{
@Override
public void run() {
try {
//暫時3秒後才輸出內容。
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("輸出線程名稱:"+Thread.currentThread().getName());
}
}
八. 線程的強制執行 join()
讓這個線程強制最先執行。
//線程的 join 方法
@Test
public void joinTest() throws Exception{
JoinRunnable joinRunnable=new JoinRunnable();
Thread thread=new Thread(joinRunnable);
//啓動
thread.start();
// 主線程有10個,副線程100個,按理是 main先執行完, 加入了 join之後,強制讓副線程先執行完。
for(int i=0;i<10;i++){
//讓當前線程死掉.
if(i==8){
//當運行8後, 讓 thread線程強制運行,即到 i=8了,不運行了,讓 其他線程運行了。
// 保證 i=8,i=9 最後輸出。
thread.join();
}
System.out.println("當前線程:"+Thread.currentThread().getName()+"運行到:"+i);
}
}
class JoinRunnable implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("輸出內容:"+Thread.currentThread().getName()+",運行到:"+i);
}
}
}
運行程序, 查看控制檯輸出:
九. 線程的暫時掛起,不執行 yield()
注意, yield() 方法,只是讓此線程釋放資源,不執行,但不能保證最後執行。 可以線程 i=8時,得到了資源, 然後判斷了i>=7, 執行 .yield() 方法,釋放資源, 忽然它又得到了資源, 那麼i=8 就會運行了。 不像 join()那樣強制。
@Test
public void yieldTest() throws Exception{
YieldRunnable yieldRunnable=new YieldRunnable();
Thread thread=new Thread(yieldRunnable);
//啓動
thread.start();
for(int i=0;i<100;i++){
System.out.println("當前線程:"+Thread.currentThread().getName()+"運行到:"+i);
}
}
class YieldRunnable implements Runnable{
@Override
public void run() {
Thread thread=Thread.currentThread();
for(int i=0;i<10;i++){
if(i>=7){
//級別設置小點, 讓其不執行。
thread.setPriority(Thread.MIN_PRIORITY);
Thread.yield();
}
System.out.println("輸出內容:"+thread.getName()+",運行到:"+i);
}
}
}
運行程序,查看控制檯輸出
這兒的 i=7,i=8,i=9 就得到了資源,執行了,而不是強制最後執行。
十. 打斷休眠 interrupt()
主要用於 打斷 休眠。
@Test
public void interTest() throws Exception{
InterruptRunnable interruptRunnable=new InterruptRunnable();
Thread thread=new Thread(interruptRunnable);
//啓動
thread.start();
//休眠兩秒
Thread.sleep(2000);
//兩秒之後,進行打斷, 副線程應該還在休眠的狀態上。
thread.interrupt();
Thread.sleep(5000);
}
class InterruptRunnable implements Runnable{
@Override
public void run() {
System.out.println("開始進行休眠");
try {
Thread.sleep(5000);
System.out.println("休眠結束");
} catch (InterruptedException e) {
System.out.println("休眠被打斷");
}
System.out.println("退出休眠");
}
}
運行程序,
十.一 設置停止和重啓
以前 是有 stop() 這樣的方法的,後來被拋棄了, 用標誌位進行設置關閉和啓動。
class MyRunnableDemo implements Runnable{
private boolean isRun=true;
@Override
public void run() {
//定義此標識位
while(isRun){
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("打印輸出");
}
}
//通過標識位進行相應的控制
public void stop(){
this.isRun=false;
}
public void restart(){
this.isRun=true;
run();
}
}
public class StopDemo {
public static void main(String[] args) {
MyRunnableDemo myRunnableDemo=new MyRunnableDemo();
Thread thread=new Thread(myRunnableDemo);
System.out.println("開始啓動");
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunnableDemo.stop();
System.out.println("停止");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("重新啓動");
myRunnableDemo.restart();
}
}
運行程序,查看控制檯。
這就是 Thread 類的常用方法,必須要掌握使用。
謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!