1 前言
線程創(chuàng)建線程的方法一般可以分為四類(lèi):
- 通過(guò)實(shí)現(xiàn)Runnable接口來(lái)創(chuàng)建Thread線程
- 通過(guò)實(shí)現(xiàn)Callable接口來(lái)創(chuàng)建Thread線程
- 通過(guò)繼承Thread類(lèi)來(lái)創(chuàng)建一個(gè)線程
- 使用Executor框架來(lái)創(chuàng)建線程
2 創(chuàng)建線程的四種方式
2.1 實(shí)現(xiàn)Runnable接口創(chuàng)建Thread
通過(guò)實(shí)現(xiàn)Runnable接口來(lái)創(chuàng)建Thread線程,其步驟可以分為以下幾步
- 步驟1:創(chuàng)建一個(gè)類(lèi)實(shí)現(xiàn)Runnable接口
class TestRunnable implements Runnable{
public void run(){
}
}
- 步驟2:創(chuàng)建一個(gè)類(lèi)對(duì)象
Runnable testRunnable = new TestRunnable();
- 步驟3:由Runnable創(chuàng)建一個(gè)Thead對(duì)象
Thread testThread = new Thread(testRunnable);
步驟4:?jiǎn)?dòng)線程:
testThread.start();
至此,通過(guò)實(shí)現(xiàn)Runnable接口來(lái)創(chuàng)建線程的步驟完成。
代碼實(shí)現(xiàn)如下所示:
(1)TestRunnable類(lèi)
package com.yds.test;
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO 自動(dòng)生成的方法存根
int i=0;
while(i<10){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自動(dòng)生成的 catch 塊
e.printStackTrace();
}
i++;
}
}
}
(2)Test類(lèi)調(diào)用
package com.yds.test;
public class Test {
public static void main(String[] args) {
// TODO 自動(dòng)生成的方法存根
//使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程
Runnable testRunnable = new TestRunnable();
Thread testThread = new Thread(testRunnable);
testThread.start();
}
}
2.2 實(shí)現(xiàn)Callable接口來(lái)創(chuàng)建Thread線程
Callable是一個(gè)接口,只有一個(gè)call方法,用Callable接口創(chuàng)建Thread線程的步驟如下:
- 步驟1:創(chuàng)建實(shí)現(xiàn)Callable接口的類(lèi)TestCallable
package com.yds.test;
import java.util.concurrent.Callable;
public class TestCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// TODO 自動(dòng)生成的方法存根
int i=0;
while(i<10){
System.out.println(i);
Thread.sleep(1000);
i++;
}
return i;
}
}
- 步驟2:創(chuàng)建一個(gè)類(lèi)對(duì)象
TestCallable testCallable = new TestCallable();
- 步驟3:有Callable創(chuàng)建一個(gè)FutureTask對(duì)象
FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
- 步驟4:由FutureTask對(duì)象創(chuàng)建一個(gè)Thread對(duì)象
Thread thread = new Thread(task);
- 步驟5:?jiǎn)?dòng)線程
thread.start();
FutureTask的get方法是返回Callable里的call返回的值,如果call方法里面是耗時(shí)任務(wù),則get方法會(huì)阻塞主線程。
代碼實(shí)現(xiàn)如下:
TestCallable類(lèi):
package com.yds.test;
import java.util.concurrent.Callable;
public class TestCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// TODO 自動(dòng)生成的方法存根
int i=0;
while(i<10){
System.out.println(i);
Thread.sleep(1000);
i++;
}
return i;
}
}
Test調(diào)用
package com.yds.test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) {
//1. 使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程
// Runnable testRunnable = new TestRunnable();
// Thread testThread = new Thread(testRunnable);
// testThread.start();
//2. 使用Callable和Future創(chuàng)建線程
TestCallable testCallable = new TestCallable();
FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
Thread thread = new Thread(task);
thread.start();
}
}
2.3 繼承Thread類(lèi)來(lái)創(chuàng)建線程
- 步驟1:定義一個(gè)繼承Thread類(lèi)的子類(lèi)
public class TestThread extends Thread{
@Override
public void run() {
// TODO 自動(dòng)生成的方法存根
}
}
- 步驟2:構(gòu)造子類(lèi)的一個(gè)對(duì)象
TestThread testThread = new TestThread();
- 步驟3:?jiǎn)?dòng)線程
testThread.start();
代碼示例如下:
TestThread類(lèi)
package com.yds.test;
public class TestThread extends Thread{
@Override
public void run() {
// TODO 自動(dòng)生成的方法存根
int i = 0;
while(i<10){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自動(dòng)生成的 catch 塊
e.printStackTrace();
}
i++;
}
}
}
Test調(diào)用
package com.yds.test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) {
//1. 使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程
// Runnable testRunnable = new TestRunnable();
// Thread testThread = new Thread(testRunnable);
// testThread.start();
//2. 使用Callable和Future創(chuàng)建線程
// TestCallable testCallable = new TestCallable();
// FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
// Thread thread = new Thread(task);
// thread.start();
//3. 繼承Thread創(chuàng)建線程
TestThread testThread = new TestThread();
testThread.start();
}
}
2.4 使用Executor框架來(lái)創(chuàng)建線程池
Executors類(lèi)中包含以下四個(gè)創(chuàng)建線程池方法。
| 方法名 | 描述 |
|---|---|
| newCachedThreadPool() | 創(chuàng)建一個(gè)可以緩存的線程池,如果線程池中有線程可用,則復(fù)用該線程,如果線程不可用,則創(chuàng)建一個(gè)新的線程并加入線程池中。終止并從緩存池中移除那些60秒未被使用的線程。 |
| newFixedThreadPool | 創(chuàng)建固定數(shù)目線程的線程池。 |
| newSingleThreadExecutor | 創(chuàng)建一個(gè)單線程化的Executor |
| newScheduledThreadPool | 創(chuàng)建一個(gè)支持定時(shí)及周期性的任務(wù)執(zhí)行的線程池,多數(shù)情況下可用來(lái)替代Timer類(lèi)。 |
- Executor執(zhí)行Runnable任務(wù)
package com.yds.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) {
//1. 使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程
// Runnable testRunnable = new TestRunnable();
// Thread testThread = new Thread(testRunnable);
// testThread.start();
//2. 使用Callable和Future創(chuàng)建線程
// TestCallable testCallable = new TestCallable();
// FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
// Thread thread = new Thread(task);
// thread.start();
//3. 繼承Thread創(chuàng)建線程
// TestThread testThread = new TestThread();
// testThread.start();
// 4. 使用Executor執(zhí)行Runnable創(chuàng)建線程
ExecutorService executorServicec = Executors.newCachedThreadPool();
executorServicec.execute(new TestRunnable());
executorServicec.shutdown();
}
}
- Executor執(zhí)行Callable創(chuàng)建線程
package com.yds.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) {
//1. 使用實(shí)現(xiàn)Runnable接口創(chuàng)建線程
// Runnable testRunnable = new TestRunnable();
// Thread testThread = new Thread(testRunnable);
// testThread.start();
//2. 使用Callable和Future創(chuàng)建線程
// TestCallable testCallable = new TestCallable();
// FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
// Thread thread = new Thread(task);
// thread.start();
//3. 繼承Thread創(chuàng)建線程
// TestThread testThread = new TestThread();
// testThread.start();
// 4. 使用Executor執(zhí)行Runnable創(chuàng)建線程
// ExecutorService executorServicec = Executors.newCachedThreadPool();
// executorServicec.execute(new TestRunnable());
// executorServicec.shutdown();
//5. 使用Executor執(zhí)行Callable創(chuàng)建線程
ExecutorService executorServicec = Executors.newCachedThreadPool();
TestCallable testCallable = new TestCallable();
FutureTask<Integer> task = new FutureTask<Integer>(testCallable);
executorServicec.execute(task);
}
}