線程如何創建 創建線程有三種方式:繼承Thread類;無返回值的Runnable;有返回值的Callable 示例如下 執行結果 線程相關的基礎方法 wait:獲取鎖對象monitor的線程執行wait方法,將會釋放對monitor的控制權,其他線程可以獲取到鎖對象的monitor,執行notify ...
線程如何創建
創建線程有三種方式:繼承Thread類;無返回值的Runnable;有返回值的Callable
示例如下
package com.rcl.platform.demo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CreateThread {
public static class TestThread extends Thread {
@Override
public void run() {
System.out.println("--繼承thread--");
}
}
public static class TestRunnable implements Runnable {
@Override
public void run() {
System.out.println("--runnable沒有返回值--");
}
}
public static class TestCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("--callable有返回值--");
return "test-callable";
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
Thread thread = new Thread(new TestThread());
thread.start();
thread = new Thread(new TestRunnable());
thread.start();
FutureTask<String> ft = new FutureTask<>(new TestCallable());
thread = new Thread(ft);
thread.start();
System.out.println(ft.get());
}
}
執行結果
--繼承thread--
--runnable沒有返回值--
--callable有返回值--
test-callable
線程相關的基礎方法
wait:獲取鎖對象monitor的線程執行wait方法,將會釋放對monitor的控制權,其他線程可以獲取到鎖對象的monitor,執行notify喚醒wait線程
notify/notifyall:獲取到monitor,喚醒曾經獲取到monitor執行wait正在處於等待的線程(線程狀態為WAITING,TIMED_WAITING)
sleep:線程休眠
yield:yield方法的作用是暫停當前線程,以便其他線程有機會執行,不過不能指定暫停的時間,並且也不能保證當前線程馬上停止。yield方法只是將Running狀態轉變為Runnable狀態(不能完全保證,最好少用)
join:join方法的作用是父線程等待子線程執行完成後再執行,換句話說就是將非同步執行的線程合併為同步的線程,如:如果在mian線程執行的過程中執行t1.join方法,那麼將轉而執行t1線程,t1線程執行完畢後執行mian線程
package com.rcl.platform.demo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class JoinTest {
public static class TestThread extends Thread {
@Override
public void run() {
for(int i=0; i<10; i++){
System.out.println("第" + i + "次執行");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
TestThread thread = new TestThread();
thread.start();
thread.join();
System.out.println("等待thread執行完畢後main線程結束");
}
}
執行結果
第0次執行 第1次執行 第2次執行 第3次執行 第4次執行 第5次執行 第6次執行 第7次執行 第8次執行 第9次執行 等待thread執行完畢後main線程結束
interrupt:他的作用是“停止”當前線程的運行,為什麼加上一個引號,它只在特殊情況下有用,像線程調用了wait,sleep,join等可中斷的阻塞方法 後,調用interrupt就會拋出InterruptedException異常。其實它稱為協作停止。調用了這個方法後線程除了特殊情況外別的時候並不會停止,它發送一個停止請求,並且由線程記錄下來(實際上就是有一個為bool的變數,當為true時就表示有停止線程運行請求)。所以說線程真正的停止需要我們自己去檢查是否有停止線程的請求,當有線程停止請求時停用當前線程。和他配套是使用的有
public static boolean interrupted()
public boolean isInterrupted()
package com.rcl.platform.demo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class JoinTest {
public static class TestThread extends Thread {
@Override
public void run() {
for(int i=0; i<1000000000; i++){
System.out.println("TestThread第" + i + "次執行");
if(Thread.interrupted()){
return;
}
}
}
}
public static class TestThreadSleep extends Thread {
@Override
public void run() {
for(int i=0; i<10; i++){
System.out.println("TestThreadSleep第" + i + "次執行");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Thread.interrupted()){
return;
}
}
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
TestThread thread = new TestThread();
thread.start();
thread.interrupt();
TestThreadSleep threadSleep = new TestThreadSleep();
threadSleep.start();
threadSleep.interrupt();
}
}
執行結果
TestThread第0次執行
TestThreadSleep第0次執行
java.lang.InterruptedException: sleep interruptedTestThreadSleep第1次執行
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.rcl.platform.demo.JoinTest$TestThreadSleep.run(JoinTest.java:27)
TestThreadSleep第2次執行
TestThreadSleep第3次執行
TestThreadSleep第4次執行
TestThreadSleep第5次執行
TestThreadSleep第6次執行
TestThreadSleep第7次執行
TestThreadSleep第8次執行
TestThreadSleep第9次執行
線程狀態
1、java線程有6中狀態,分別為NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED詳解java.lang.Thread$State枚舉類
2、線程初始化為NEW狀態,該狀態表示還未調用start方法
3、執行線程調用start方法,線程狀態轉換為RUNNABLE(包括競爭到CPU時間真正意義的執行和沒有競爭到CPU時間等待下一個CPU時間的狀態)
4、BLOCKED狀態為鎖競爭,沒有競爭到鎖為BLOCKED,等待擁有鎖的線程釋放鎖,進入RUNNABLE狀態
5、WAITING狀態為競爭到鎖,執行wait方法,又釋放鎖,本線程進入WAITING,等待其他線程喚醒notify,notifyall,如果不喚醒,將一直處於WAITING狀態
6、TIMED_WAITING為執行sleep join或者有時限的等待
7、線程執行完畢,線程處於TERMINATED狀態
線程狀態變化
package com.rcl.platform.demo;
import java.util.concurrent.TimeUnit;
public class ThreadState {
public static void main( String[] args ) throws InterruptedException {
System.out.println("-------------NEW-------------");
Thread thread = new Thread();
System.out.println(thread.getState() + ":" + (thread.getState() == Thread.State.NEW));
System.out.println("-------------分割線-------------");
System.out.println("-------------RUNNABLE、TERMINATED-------------");
thread = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
System.out.println(thread.getState() + ":" + (thread.getState() == Thread.State.TERMINATED));
System.out.println("-------------分割線-------------");
System.out.println("-------------RUNNABLE、TIMED_WAITING-------------");
thread = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
System.out.println("sleep 進入 TIMED_WAITING");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
System.out.println(thread.getState() );
TimeUnit.SECONDS.sleep(2);
System.out.println("-------------分割線-------------");
System.out.println("-------------RUNNABLE、TIMED_WAITING-------------");
final Thread mainThread = Thread.currentThread();
thread = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getState() + ":" + (Thread.currentThread().getState() == Thread.State.RUNNABLE));
try {
System.out.println("join 進入 TIMED_WAITING");
System.out.println("mainThread: " + mainThread.getState());
TimeUnit.SECONDS.timedJoin(mainThread, 2);//先執行mainthread
System.out.println("mainThread: " + mainThread.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("testThread: " + thread.getState() );
System.out.println("-------------分割線-------------");
System.out.println("-------------RUNNABLE、WAITING-------------");
Object lock = new Object();
final Thread mainThread1 = Thread.currentThread();
thread = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
try {
System.out.println("wait 進入 WAITING");
lock.wait();
System.out.println("mainThread1: " + mainThread1.getState() );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("testThread: " + thread.getState() );
synchronized (lock) {
lock.notifyAll();
}
TimeUnit.SECONDS.sleep(1);
System.out.println("-------------分割線-------------");
Thread thread1 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
}
}
});
thread2.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("thread2: " + thread2.getState() );
}
}
執行結果
-------------NEW-------------
NEW:true
-------------分割線-------------
-------------RUNNABLE、TERMINATED-------------
RUNNABLE:true
TERMINATED:true
-------------分割線-------------
-------------RUNNABLE、TIMED_WAITING-------------
RUNNABLE:true
sleep 進入 TIMED_WAITING
TIMED_WAITING
-------------分割線-------------
-------------RUNNABLE、TIMED_WAITING-------------
RUNNABLE:true
join 進入 TIMED_WAITING
mainThread: TIMED_WAITING
testThread: TIMED_WAITING
-------------分割線-------------
-------------RUNNABLE、WAITING-------------
wait 進入 WAITING
mainThread: TIMED_WAITING
testThread: WAITING
mainThread1: TIMED_WAITING
-------------分割線-------------
thread2: BLOCKED
歡迎加入學習交流群569772982,大家一起學習交流。