1、繼承Thread類
Thread類本質上是實現了 Runnable 接口的一個實例,代表一個線程的實例。啓動線程的唯一方法就是通過Thread 類的 start()
實例方法。 start() 方法是一個 native 方法,它將啓動一個新線程,並執行 run()
方法。
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
MyThread myThread1 = new MyThread();
myThread1.start();
2、實現Runnable接口
如果自己的類已經extends另一個類,就無法直接extends Thread,此時,可以實現一個 Runnable接口。
public class MyThread extends OtherClass implements Runnable {
public void run() {
System.out.println("MyThread.run()");
}
}
//啓動MyThread,需要首先實例化一個Thread,並傳入自己的MyThread實例:
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
//事實上,當傳入一個Runnable target參數給Thread後,Thread的run()方法就會調用 target.run()
public void run() {
if (target != null) {
target.run();
}
}
3、ExecutorService、Callable<Class>、Future 有返回值線程
有返回值的任務必須實現Callable接口,類似的,無返回值的任務必須Runnable接口。執行 Callable任務後,可以獲取一個Future的對象,在該對象上調用get就可以獲取到Callable任務 返回的Object了,再結合線程池接口ExecutorService就可以實現傳說中有返回結果的多線程 了。
//創建一個線程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
// 創建多個有返回值的任務
List<Future> list = new ArrayList<Future>();
for (int i = 0; i < taskSize; i++) {
Callable c = new MyCallable(i + " ");
// 執行任務並獲取Future對象
Future f = pool.submit(c);
list.add(f);
}
// 關閉線程池
pool.shutdown();
// 獲取所有併發任務的運行結果
for (Future f : list) {
// 從Future對象上獲取任務的返回值,並輸出到控制檯
System.out.println("res:" + f.get().toString());
}
4、基於線程池的方式
線程和數據庫連接這些資源都是非常寶貴的資源。那麼每次需要的時候創建,不需要的時候銷燬,是非常浪費資源的。那麼我們就可以使用緩存的策略,也就是使用線程池。
// 創建線程池
ExecutorService threadPool = Executors.newFixedThreadPool(10);
while(true) {
threadPool.execute(new Runnable() {
// 提交多個線程任務,並執行
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running .."); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}