本文主要回答3個問題:是什麼,爲什麼,怎麼弄?
1、線程是什麼?
附一段【百度百科】的介紹:
線程(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。在Unix System V及SunOS中也被稱爲輕量進程(lightweight processes),但輕量進程更多指內核線程(kernel thread),而把用戶線程(user thread)稱爲線程。
打個比方,一個系統中,類似於我們一個公司,每個人都是一個線程,人,就是公司分派任務的最小維度,最小單位,公司不能說,你的左手去打字,右手幫我衝一杯咖啡;這樣是不可以的(除非你很秀);進程就可以理解你們一個小組;
2、爲什麼要用線程;
線程主要講的就是多線程;一個人如果類比一個線程的話,多個人的工作團隊就是多線程;一個人的工作量,一般比不上多個人的工作量;提高整個系統的效率;注意,這裏不是提升單個線程的工作效率;我公司就我一個人,我啥都會,啥也知道,做一些簡單的工作肯定是我一個人效率高;但是如果多個人團隊協作;任務分配,溝通,爭奪資源(爭奪客戶,爭奪優先級),都是會有內耗的,對於一些簡單的工作,多線程的每個人的效率一般是低於一個人(理性人)工作的;多線程的優勢在於:
- 人多系統的力量大,速度快,衆人拾柴火焰高;
- 互相協助,共同承擔任務,減輕單個線程的壓力;
- 降低風險:防止一個線程的癱瘓造成整個系統癱瘓;(單線程:一人生病,系統癱瘓;多線程:每個人分擔一些,系統還能運行);
3、如何實現線程?
實現線程的方式有4中:
- 實現Runnable接口;
- 實現Callable接口;
- 繼承Thread類,然後new 出該線程;
- 線程池創建;
①、實現Runnable接口:
public class TestRunnable implements Runnable {
@Override
public void run() {
System.out.println("實現Runnable接口");
}
}
截圖:
運行該線程:
當然,你也可以直接new 一個Runnable接口,再實現,也是可以的;
②、實現Callable接口:
這裏,我們在這個線程中返回一個double類型的隨機數;
import java.util.concurrent.Callable;
public class CallableThread implements Callable {
@Override
public Object call() throws Exception {
return Math.random();
}
}
測試運行結果:
③、繼承Thread類,然後new出該新類;
public class TestExtendsThread extends Thread {
@Override
public void run() {
System.out.println("繼承Thread類");
}
}
測試運行結果:
④、使用線程池創建線程;
@Test
public void testThreadPool(){
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
for(int i=0;i<5;i++){
newFixedThreadPool.submit(new TestExtendsThread());
}
}
測試運行結果:
全部代碼如下:
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestThread {
/**
* 測試繼承了Runnable接口的線程;
*/
@Test
void runable(){
// TestRunnable testRunnable = new TestRunnable();
// testRunnable.run();
/**
* 直接
*/
new Runnable() {
@Override
public void run() {
System.out.println("直接new 一個Runnable可運行接口,然後實現;");
}
}.run();
}
/**
* 測試具有返回值的線程
* @throws Exception 拋出異常
*/
@Test
void testCallable() throws Exception {
CallableThread callableThread = new CallableThread();
double randomNum = (double)callableThread.call();
System.out.println(randomNum);
}
/**
* 測試繼承Thread類的線程
* @throws Exception 拋出異常
*/
@Test
void testNewThread() throws Exception {
TestExtendsThread thread = new TestExtendsThread();
thread.start();
}
/**
* 使用線程池創建線程;
*/
@Test
public void testThreadPool(){
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
for(int i=0;i<5;i++){
newFixedThreadPool.submit(new TestExtendsThread());
}
}
}