多執行緒常用操作方法(sleep、yield、join)
執行緒的命名與取得
執行緒的命名:
- 通過構造方法在建立執行緒時設定執行緒名稱
- 直接繼承Thread類: public Thread (String name);
- Runable或者Callable介面實現多執行緒: public Thread (Runable target,String name);
- 在建立執行緒之後設定執行緒名稱
- public final synchronized void setName(String name); //表示子類只能用
取得執行緒名稱:
- public final String getName( );
如果想取得當前執行緒物件:
//在Thread類中提供有一個方法取得當前執行緒物件:
public static native Thread currentThread();
執行緒的命名與取得:
/////執行緒的命名與取得
class Mythread1 implements Runnable
{
public void run()
{
System.out.println("執行緒名為:"+Thread.currentThread().getName());
}
}
public class SetGet
{
public static void main(String[] args) {
Mythread1 thread=new Mythread1();
new Thread(thread).start(); //沒有設定執行緒名,預設從Thread-0開始
new Thread(thread).start();
new Thread(thread,"執行緒...").start(); //設定名字
}
}
public class SetGet
{
public static void main(String[] args) {
System. out.println(Thread.currentThread().getName()); //main
}
}
- 線上程啟動後,可以有setName 修改執行緒名,子執行緒名稱如果米有命名預設從Thread-0開始;
- 主方法是主執行緒,執行緒名為main;所有的執行緒都是通過主執行緒建立並啟動的。每當使用了java命令去解釋程式的時候,都表示啟動了一個新的JVM程序。而主方法只是這個程序上的一個執行緒而已。
class Mythread1 implements Runnable
{
public void run()
{
System.out.println("執行緒名為:"+Thread.currentThread().getName());
}
}
public class SetGet
{
public static void main(String[] args) {
Mythread1 thread=new Mythread1();
thread.run(); //執行緒名為:main
new Thread(thread).start(); //執行緒名為:Thread-0
}
}
從上面結果可以看出,直接呼叫run方法,並沒有啟動一個執行緒,若想要啟動一個執行緒必須呼叫Thread類的start方法。
執行緒休眠方法sleep( ) — 單位為毫秒
執行緒休眠指的是讓執行緒暫緩執行,等到了預計時間再恢復執行。
執行緒暫緩狀態改變:執行態(running)---->阻塞狀態(blocked);
等到預計時間狀態改變:阻塞態(blocked)—>就緒態(runable),到就緒態後等待系統排程。
執行緒休眠會立馬交出cpu,CPU可以去執行其他的執行緒,但是並不會釋放物件鎖,也就是說假如這個執行緒持有對某個物件的鎖,則即使呼叫sleep方法,其他執行緒也無法訪問這個物件。
public static native void sleep(long millis) throws InterruptedException //注意,會拋異常
sleep是靜態方法,通過類名來呼叫。
class Mythread2 implements Runnable
{
public void run()
{
for(int i=0;i<5;i++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class SleepYield
{
public static void main(String[] args) {
Mythread2 thread=new Mythread2();
new Thread(thread).start();
new Thread(thread).start();
}
}
假如當執行緒Thread-0 休眠時,會立馬交出cpu,CPU會執行另一個執行緒Thread-1。
2個執行緒誰先進入run方法是不一定的,要看cpu的排程。
執行緒讓步yield( ):
執行緒讓步是暫停執行當前的執行緒物件,並執行其他執行緒。
public static native void yield();
暫定時執行緒狀態改變:由執行態(running)---->就緒態(runable), 因為它只是等待cpu何時來排程,這點和sleep不同。
yield()方法會讓當前執行緒交出cpu,同樣不會釋放鎖,但是yield()方法無法控制具體交出cpu的時間,並且yield()方法只能讓擁有相同優先順序的執行緒有獲取cpu的機會。
//yield
class Mythread2 implements Runnable
{
public void run()
{
for(int i=0;i<5;i++)
{
Thread.yield();
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class SleepYield
{
public static void main(String[] args) {
Mythread2 thread=new Mythread2();
new Thread(thread).start();
new Thread(thread).start();
}
}
呼叫yield後並不知道什麼時候交出cpu。
等待執行緒停止-----join( )方法
等待該執行緒終止。意思就是如果在主執行緒中一個執行緒呼叫該方法時就會讓主執行緒休眠,讓呼叫該方法的執行緒run方法先執行完畢之後在開始執行主執行緒。
/////join方法
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
class Mythread2 implements Runnable
{
public void run()
{
System.out.print("主執行緒睡眠前的時間:");
printTime();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("主執行緒喚醒時間");
printTime();
}
private void printTime()
{
Date date=new Date();
DateFormat dateFormat=new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
String time=dateFormat.format(date);
System.out.println(time);
}
}
public class SleepYield
{
public static void main(String[] args) throws InterruptedException {
Mythread2 thread=new Mythread2();
Thread thread1=new Thread(thread,"子執行緒1");
thread1.start();
System.out.println(Thread.currentThread().getName());
thread1.join(); //子執行緒1呼叫join,會讓主執行緒休眠,直至子執行緒1的run執行結束
System.out.println("程式碼結束"); //最後列印
}
}
子執行緒1在主執行緒中呼叫join方法,會讓主執行緒休眠,直至子執行緒1的run方法結束。