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