Thread.currentThread()方法可以獲得當(dāng)前線程。
Java中的任何一段代碼都是執(zhí)行在某個(gè)線程當(dāng)中的. 執(zhí)行當(dāng)前代碼的線程就是當(dāng)前線程。
同一段代碼可能被不同的線程執(zhí)行,因此當(dāng)前線程是相對的,Thread.currentThread()方法的返回值是在代碼實(shí)際運(yùn)行時(shí)候的線程對象。
package com.wkcto.threadmehtod;
/**
* 定義線程類
* 分別在構(gòu)造方法中和run方法中打印當(dāng)前線程
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread1 extends Thread {
public SubThread1(){
System.out.println("構(gòu)造方法打印當(dāng)前線程的名稱: " + Thread.currentThread().getName());
}
@Override
public void run() {
System.out.println("run方法打印當(dāng)前線程名稱:" + Thread.currentThread().getName());
}
}
package com.wkcto.threadmehtod;
/**
* 測試當(dāng)前線程
* Author : 蛙課網(wǎng)老崔
*/
public class Test01CurrentThread {
public static void main(String[] args) {
System.out.println("main方法中打印當(dāng)前線程:" + Thread.currentThread().getName());
//創(chuàng)建子線程, 調(diào)用SubThread1()構(gòu)造方法, 在main線程中調(diào)用構(gòu)造方法,所以構(gòu)造方法中 的當(dāng)前線程就是main線程
SubThread1 t1 = new SubThread1();
// t1.start(); //啟動子線程,子線程會調(diào)用run()方法,所以run()方法中 的當(dāng)前線程就是Thread-0子線程
t1.run(); //在main方法中直接調(diào)用run()方法,沒有開啟新的線程,所以在run方法中的當(dāng)前線程就是main線程
}
}
package com.wkcto.threadmehtod;
/**
* 當(dāng)前線程的復(fù)雜案例
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread2 extends Thread {
public SubThread2(){
System.out.println("構(gòu)造方法中,Thread.currentThread().getName() : " + Thread.currentThread().getName() );
System.out.println("構(gòu)造方法,this.getName() : " + this.getName());
}
@Override
public void run() {
System.out.println("run方法中,Thread.currentThread().getName() : " + Thread.currentThread().getName() );
System.out.println("run方法,this.getName() : " + this.getName());
}
}
package com.wkcto.threadmehtod;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test02CurrentThread {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建子線程對象
SubThread2 t2 = new SubThread2();
t2.setName("t2"); //設(shè)置線程的名稱
t2.start();
Thread.sleep(500); //main線程睡眠500毫秒
//Thread(Runnable)構(gòu)造方法形參是Runnable接口,調(diào)用時(shí)傳遞的實(shí)參是接口的實(shí)現(xiàn)類對象
Thread t3 = new Thread(t2);
t3.start();
}
}
etName()/getName()
thread.setName(線程名稱), 設(shè)置線程名稱。
thread.getName()返回線程名稱。
通過設(shè)置線程名稱,有助于程序調(diào)試,提高程序的可讀性, 建議為每個(gè)線程都設(shè)置一個(gè)能夠體現(xiàn)線程功能的名稱。
thread.isAlive()判斷當(dāng)前線程是否處于活動狀態(tài)。
活動狀態(tài)就是線程已啟動并且尚未終止。
package com.wkcto.threadmehtod.p2IsAlive;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread3 extends Thread {
@Override
public void run() {
System.out.println("run方法, isalive = " + this.isAlive()); //運(yùn)行狀態(tài),true
}
}
package com.wkcto.threadmehtod.p2IsAlive;
/**
* 測試線程的活動狀態(tài)
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
SubThread3 t3 = new SubThread3();
System.out.println("begin==" + t3.isAlive()); //false,在啟動線程之前
t3.start();
System.out.println("end==" + t3.isAlive()); //結(jié)果不一定,打印這一行時(shí),如果t3線程還沒結(jié)束就返回true, 如果t3線程已結(jié)束,返回false
}
}
sleep()
Thread.sleep(millis); 讓當(dāng)前線程休眠指定的毫秒數(shù)。
當(dāng)前線程是指Thread.currentThread()返回的線程。
package com.wkcto.threadmehtod.p3sleep;
/**
* 子線程休眠
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread4 extends Thread {
@Override
public void run() {
try {
System.out.println("run, threadname=" + Thread.currentThread().getName()
+ " ,begin= " + System.currentTimeMillis());
Thread.sleep(2000); //當(dāng)前線程睡眠2000毫秒
System.out.println("run, threadname=" + Thread.currentThread().getName()
+ " ,end= " + System.currentTimeMillis());
} catch (InterruptedException e) {
//在子線程的run方法中, 如果有受檢異常(編譯時(shí)異常)需要處理,只有選擇捕獲處理,不能拋出處理
e.printStackTrace();
}
}
}
package com.wkcto.threadmehtod.p3sleep;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
SubThread4 t4 = new SubThread4();
System.out.println("main__begin = " + System.currentTimeMillis());
// t4.start(); //開啟新的線程
t4.run(); //在main線程中調(diào)用實(shí)例方法run(),沒有開啟新的線程
System.out.println("main__end = " + System.currentTimeMillis());
}
}
package com.wkcto.threadmehtod.p3sleep;
/**
* 使用線程休眠Thread.sleep完成一個(gè)簡易的計(jì)時(shí)器
* Author : 蛙課網(wǎng)老崔
*/
public class SimpleTimer {
public static void main(String[] args) {
int remaining = 60; //從60秒開始計(jì)時(shí)
//讀取main方法的參數(shù)
if (args.length == 1){
remaining = Integer.parseInt(args[0]);
}
while(true){
System.out.println("Remaining: " + remaining);
remaining--;
if (remaining < 0 ){
break;
}
try {
Thread.sleep(1000); //線程休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Done!!");
}
}
getId()
thread.getId()可以獲得線程的唯一標(biāo)識。
注意:
某個(gè)編號的線程運(yùn)行結(jié)束后,該編號可能被后續(xù)創(chuàng)建的線程使用。
重啟的JVM后,同一個(gè)線程的編號可能不一樣。
package com.wkcto.threadmehtod.p4getid;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread5 extends Thread {
@Override
public void run() {
System.out.println("thread name = " + Thread.currentThread().getName()
+ ", id == " + this.getId() );
}
}
package com.wkcto.threadmehtod.p4getid;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
System.out.println( Thread.currentThread().getName() + " , id = " + Thread.currentThread().getId());
//子線程的id
for(int i = 1; i <= 100; i++){
new SubThread5().start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
yield()
Thread.yield()方法的作用是放棄當(dāng)前的CPU資源。
package com.wkcto.threadmehtod.p5yield;
/**
* 線程讓步
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread6 extends Thread {
@Override
public void run() {
long begin = System.currentTimeMillis();
long sum = 0;
for(int i = 1; i <= 1000000; i++){
sum += i;
Thread.yield(); //線程讓步, 放棄CPU執(zhí)行權(quán)
}
long end = System.currentTimeMillis();
System.out.println("用時(shí): " + (end - begin));
}
}
package com.wkcto.threadmehtod.p5yield;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
//開啟子線程,計(jì)算累加和
SubThread6 t6 = new SubThread6();
t6.start();
//在main線程中計(jì)算累加和
long begin = System.currentTimeMillis();
long sum = 0;
for(int i = 1; i <= 1000000; i++){
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("main方法 , 用時(shí): " + (end - begin));
}
}
setPriority()
thread.setPriority( num ); 設(shè)置線程的優(yōu)先級。
java線程的優(yōu)先級取值范圍是 1 ~ 10 , 如果超出這個(gè)范圍會拋出異常IllegalArgumentException。
在操作系統(tǒng)中,優(yōu)先級較高的線程獲得CPU的資源越多。
線程優(yōu)先級本質(zhì)上是只是給線程調(diào)度器一個(gè)提示信息,以便于調(diào)度器決定先調(diào)度哪些線程. 注意不能保證優(yōu)先級高的線程先運(yùn)行。
Java優(yōu)先級設(shè)置不當(dāng)或者濫用可能會導(dǎo)致某些線程永遠(yuǎn)無法得到運(yùn)行,即產(chǎn)生了線程饑餓。
線程的優(yōu)先級并不是設(shè)置的越高越好,一般情況下使用普通的優(yōu)先級即可,即在開發(fā)時(shí)不必設(shè)置線程的優(yōu)先級。
線程的優(yōu)先級具有繼承性, 在A線程中創(chuàng)建了B線程,則B線程的優(yōu)先級與A線程是一樣的。
package com.wkcto.threadmehtod.p6priority;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class ThreadA extends Thread {
@Override
public void run() {
long begin = System.currentTimeMillis();
long sum = 0 ;
for(long i = 0 ; i<= 10000000000L; i++){
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("thread a : " + (end - begin));
}
}
package com.wkcto.threadmehtod.p6priority;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.setPriority(1);
threadA.start();
ThreadB threadB = new ThreadB();
threadB.setPriority(10);
threadB.start();
}
}
interrupt()
中斷線程。
注意調(diào)用interrupt()方法僅僅是在當(dāng)前線程打一個(gè)停止標(biāo)志,并不是真正的停止線程。
package com.wkcto.threadmehtod.p7interrupt;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class SubThread2 extends Thread {
@Override
public void run() {
super.run();
for(int i = 1; i <= 10000; i++){
//判斷線程的中斷標(biāo)志,線程有 isInterrupted()方法,該方法返回線程的中斷標(biāo)志
if ( this.isInterrupted() ){
System.out.println("當(dāng)前線程的中斷標(biāo)志為true, 我要退出了");
// break; //中斷循環(huán), run()方法體執(zhí)行完畢, 子線程運(yùn)行完畢
return; //直接結(jié)束當(dāng)前run()方法的執(zhí)行
}
System.out.println("sub thread --> " + i);
}
}
}
package com.wkcto.threadmehtod.p7interrupt;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class Test02 {
public static void main(String[] args) {
SubThread2 t1 = new SubThread2();
t1.start(); ///開啟子線程
//當(dāng)前線程是main線程
for(int i = 1; i<=100; i++){
System.out.println("main ==> " + i);
}
//中斷子線程
t1.interrupt(); ////僅僅是給子線程標(biāo)記中斷,
}
}
setDaemon()
Java中的線程分為用戶線程與守護(hù)線程。
守護(hù)線程是為其他線程提供服務(wù)的線程,如垃圾回收器(GC)就是一個(gè)典型的守護(hù)線程。
守護(hù)線程不能單獨(dú)運(yùn)行, 當(dāng)JVM中沒有其他用戶線程,只有守護(hù)線程時(shí),守護(hù)線程會自動銷毀, JVM會退出。
package com.wkcto.threadmehtod.p8daemon;
/**
* Author : 蛙課網(wǎng)老崔
*/
public class SubDaemonThread extends Thread {
@Override
public void run() {
super.run();
while(true){
System.out.println("sub thread.....");
}
}
}
package com.wkcto.threadmehtod.p8daemon;
/**
* 設(shè)置線程為守護(hù)線程
* Author : 蛙課網(wǎng)老崔
*/
public class Test {
public static void main(String[] args) {
SubDaemonThread thread = new SubDaemonThread();
//設(shè)置線程為守護(hù)線程
thread.setDaemon(true); //設(shè)置守護(hù)線程的代碼應(yīng)該在線程啟動前
thread.start();
//當(dāng)前線程為main線程
for(int i = 1; i <= 10 ; i++){
System.out.println("main== " + i);
}
//當(dāng)main線程結(jié)束, 守護(hù)線程thread也銷毀了
}
}