多線程
概述:
什麼是線程?
os可以同時執行很多任務,這些任務就是進程,每個進程也可以同時執行很多任務,這個任務就是線程。
爲什麼要多線程?
1.線程協作提高效率:例如:經典的打印機例子、多線程下載等
2.提供某種額外的相關服務:好比手機廠商提供周邊產品生產,廠商不可能他能停下當前手機的生產而專注周邊生產,所以會新產生一個部門去做周邊設備。
3.性能的提高:內存共享
創建線程的2種方法
1.寫一個類(繼承Thread 並重寫run方法),實例化這個類,並調用start()方法。 見 例中的方式一演示
2.實現了Runnable接口 並實現其中的run方法,這個類 可以當作是Thread類的target。 見 例中的方式二演示
兩種方式的對比:
1.實現Runnable接口的同時還可以繼承其他的類,但是繼承Thread之後就不可以再繼承了。
2.target的方式更加靈活,結構更加清晰。
帶返回值的線程 見ThreadCallable類
Callable 實現方式 和Runnable類似,只不過它具有返回值的功能。
使用匿名內部類來快速定義一個線程
優點:快速,簡單,直觀
缺點:複用性差,執行體(run方法)代碼過長會影響代碼可讀性。
package com.hoonee.javase.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* 多線程示例
*
* @author Hoonee
* @mail [email protected]
*/
public class ThreadDemo {
public static void main(String[] args) throws Exception {
// 方式一演示
System.out.println(Thread.currentThread().getName() + ":開始");
for (int i = 0; i < 3; i++) {
new ThreadExt().start();
}
/*
* 1.一個繼承了Thread,並重寫了run方法的類--ThreadObj,具有多線程的功能
* 2.實例化ThreadObj並調用start方法開啓一個線程。
* 3.通過上面的例子我們可以看到main線程(主線程)的執行並不是等待所有線程執行結束才執行的。
* 4.我們創建了5個線程,這5個線程的執行互不影響,獨立執行。
*/
// 方式二:
ThreadTarget tt = new ThreadTarget();
for (int i = 0; i < 3; i++) {
new Thread(tt, "線程" + (i + 1)).start(); // 設置target的同時可以直接給線程起名字
}
// 創建一個帶返回值的線程
ThreadCallable tc = new ThreadCallable();
FutureTask<String> ft = new FutureTask<String>(tc);
new Thread(ft, "帶返回值的線程").start();
System.out.println(ft.get()); // 這裏會阻塞線程等待返回值
// 一種快捷的方式 匿名內部類
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("快捷線程~");
}
});
t1.start();
System.out.println(Thread.currentThread().getName() + ":結束");
}
}
/**
* 一個繼承了Thread,並重寫了run方法的類
*
* @author Hoonee
* @mail [email protected]
*/
class ThreadExt extends Thread {
@Override
public void run() {
super.run();
System.out.println(Thread.currentThread().getName() + ":執行中...");
try {
Thread.sleep(1000); // 這種方式可以通過this來獲得當前的線程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":執行完畢");
}
}
/**
* 一個實現了Runnable接口 並實現其中的run方法
*
* @author Hoonee
* @mail [email protected]
*/
class ThreadTarget implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":執行中...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":執行完畢");
}
}
/**
* 一個實現了Callable接口的線程target,它可以返回值 特點一:它能聲明異常 特點二:有返回值
*
* @author Hoonee
* @mail [email protected]
*/
class ThreadCallable implements Callable<String> {
@Override
public String call() throws Exception // 特點一
{
Thread.sleep(5000);
return Thread.currentThread().getName(); // 特點二
}
}