線程創建的四種方式
創建線程的方式有四種:
- 繼承Thread類;
- 實現Runnable接口;
- 實現Callable接口,通過
FutureTask
包裝器來創建Thread類; - 通過線程執行器接收實現Runnable、Callable對象,通過Future下面的submit或者execute方法執行;
繼承Thread類
package BingFa;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
/**
* 創建線程的四種方式
*
* @author lsq_adm
*
*/
public class CreateThread {
public static void createThread1(){
// 繼承Thread類
Thread t1 = new CreateThreadBy1();
t1.start();
}
}
/* 繼承Thread類*/
class CreateThreadBy1 extends Thread {
@Override
public void run() {
System.out.println(this.getName() + " 繼承Thread -- 線程1");
}
}
Thread-0 繼承Thread -- 線程1
實現Runnable接口
public class CreateThread {
public static void createThread1(){
// 實現Runnable接口
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
"實現 RUnable -- 線程2");
}
});
t2.start();
}
}
Thread-1實現 RUnable -- 線程2
實現Callable接口
通過Callable
+ FutureTask
創建的線程可以有返回值
public class CreateThread {
public static void createThread1(){
// 實現Callable的接口 ,這種方法可從線程中返回值
FutureTask ft = new FutureTask(new Callable(){
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getName()
+ "實現Callable接口 -- 線程3");
return null;
}
});
Thread t3 = new Thread(ft);
t3.start();
}
}
Thread-2實現Callable接口 -- 線程3
通過線程器ExecutorService
類
Executors + ExecutorService + Future
Executors
:提供創建多種線程池的工廠方法;
ExecutorService
:提供執行線程的方法execute(繼承自Executor
),返回Future
的submit方法;
Future
:get方法等待任務計算完成,然后檢索其結果;
public class CreateThread {
public static void createThread1(){
// 固定線程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
// ExecutorService 執行 實現Runable接口的線程 任務
fixedThreadPool.execute(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ "ExecutorService execute Runnable -- 線程4");
}
});
// ExecutorService 提交 實現Runable接口的線程 任務
Future submit = fixedThreadPool.submit(new Runnable(){
public void run() {
System.out.println(Thread.currentThread().getName()
+ "ExecutorService submit Runnable -- 線程4");
}
});
try {
// Future 的get方法 : 等待計算完成,然后檢索其結果
submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// ExecutorService 提交 實現Callable接口的線程 任務
Future<String> submit2 = fixedThreadPool.submit(new Callable(){
@Override
public String call() throws Exception {
return Thread.currentThread().getName()
+ "ExecutorService submit Callable -- 線程5";
}
});
try {
String str = submit2.get();
System.out.println(str);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 可緩存線程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 單工作線程
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 支持延遲,定時任務
ScheduledExecutorService scheduledThreadPool =
Executors.newScheduledThreadPool(5);
// 支持延遲,定時任務的單線程
ScheduledExecutorService singleThreadScheduledExecutor =
Executors.newSingleThreadScheduledExecutor();
}
}
pool-1-thread-1ExecutorService execute Runnable -- 線程4
pool-1-thread-2ExecutorService submit Runnable -- 線程5
pool-1-thread-3ExecutorService submit Callable -- 線程6
自定義線程池
自定義線程池,可以用ThreadPoolExecutor
類創建,它有多個構造方法來創建線程池,用該類很容易實現自定義的線程池;
/* 自定義線程池*/
public static void createThreadPool() {
BlockingQueue<Runnable> arrayBlockingQueue =
new ArrayBlockingQueue<Runnable>(5);
/**
* 自定義線程池的參數
* 核心線程數
* 最大線程數
* 超出核心線程的空閑線程最大保持時間
* 時間單位
* 阻塞隊列 BlockingQueue
*/
ThreadPoolExecutor pool = new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,arrayBlockingQueue);
Runnable t1 = new MyThread();
Runnable t2 = new MyThread();
Runnable t3 = new MyThread();
Runnable t4 = new MyThread();
Runnable t5 = new MyThread();
Runnable t6 = new MyThread();
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
}
class MyThread implements Runnable {
/* 線程計數器*/
private static int counter = 0;
private final int count = counter++;
public void run() {
System.out.println( count + "任務 " + Thread.currentThread().getName());
}
}
0任務 pool-1-thread-1
2任務 pool-1-thread-3
1任務 pool-1-thread-2
5任務 pool-1-threa-3
4任務 pool-1-thread-5
3任務 pool-1-thread-4