1.繼承Thread類
class MyThread extends Thread{ // 繼承Thread類桐臊,作為線程的實(shí)現(xiàn)類
private String name ; // 表示線程的名稱
public MyThread(String name){
this.name = name ; // 通過(guò)構(gòu)造方法配置name屬性
}
public void run(){ // 覆寫(xiě)run()方法津滞,作為線程 的操作主體
for(int i=0;i<10;i++){
System.out.println(name + "運(yùn)行,i = " + i) ;
}
}
};
public class ThreadDemo01{
public static void main(String args[]){
MyThread mt1 = new MyThread("線程A ") ; // 實(shí)例化對(duì)象
MyThread mt2 = new MyThread("線程B ") ; // 實(shí)例化對(duì)象
mt1.start() ; // 調(diào)用線程主體
mt2.start() ; // 調(diào)用線程主體
}
};
2.實(shí)現(xiàn)Runnable接口
class MyThread implements Runnable{ // 實(shí)現(xiàn)Runnable接口叮盘,作為線程的實(shí)現(xiàn)類
private String name ; // 表示線程的名稱
public MyThread(String name){
this.name = name ; // 通過(guò)構(gòu)造方法配置name屬性
}
public void run(){ // 覆寫(xiě)run()方法,作為線程 的操作主體
for(int i=0;i<100;i++){
System.out.println(name + "運(yùn)行,i = " + i) ;
}
}
};
public class ThreadDemo02{
public static void main(String args[]){
MyThread mt1 = new MyThread("線程A ") ; // 實(shí)例化對(duì)象
MyThread mt2 = new MyThread("線程B ") ; // 實(shí)例化對(duì)象
Thread t1 = new Thread(mt1) ; // 實(shí)例化Thread類對(duì)象
Thread t2 = new Thread(mt2) ; // 實(shí)例化Thread類對(duì)象
t1.start() ; // 啟動(dòng)多線程
t2.start() ; // 啟動(dòng)多線程
}
};
3實(shí)現(xiàn)Callable接口
需求:打印1~100之間偶數(shù)之和
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
//1.創(chuàng)建Callable接口的實(shí)現(xiàn)類
class NumThread implements Callable{
//2.重寫(xiě)call()方法
@Override
public Object call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0){
System.out.println(i);
sum += i;
}
}
return sum;
}
}
public class ThreadDemo03 {
public static void main(String[] args) {
//3.創(chuàng)建Callable接口實(shí)現(xiàn)類的對(duì)象
NumThread numThread = new NumThread();
//4.將此Callable接口實(shí)現(xiàn)類的對(duì)象作為參數(shù)傳遞到FutureTask構(gòu)造器中赠尾,創(chuàng)建FutureTask的對(duì)象
FutureTask futureTask = new FutureTask(numThread);
//5.將FutureTask的對(duì)象作為參數(shù)傳遞到Thread類的構(gòu)造器中辐马,創(chuàng)建Thread對(duì)象拷橘,并吊用start()方法
new Thread(futureTask).start();
try {
Object sum = futureTask.get();
System.out.println("總和為:" + sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
問(wèn):在創(chuàng)建多線程中,如何理解實(shí)現(xiàn)Callable接口的方式比實(shí)現(xiàn)Runnable接口的方式更強(qiáng)大喜爷?
1.call()可以有返回值
2.call()可以拋出異常冗疮,被外面的操作捕獲,獲取異常信息
3.Callable支持泛型
4.使用線程池
線程池的好處:
- 提高響應(yīng)速度(減少了創(chuàng)建新線程的時(shí)間)
- 降低資源消耗(重復(fù)利用線程池中的線程檩帐,不需要每次都創(chuàng)建)
- 便于線程管理
下面的代碼實(shí)現(xiàn)的是术幔,主進(jìn)程的兩個(gè)線程,一個(gè)線程輸出100以內(nèi)的偶數(shù)湃密,另一個(gè)線程輸出100以內(nèi)的奇數(shù):
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//輸出100以內(nèi)的偶數(shù)
class Number1 implements Runnable{
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
//輸出100以內(nèi)的奇數(shù)
class Number2 implements Runnable{
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 != 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class ThreadDemo04 {
public static void main(String[] args) {
//1. 提供指定線程數(shù)量的線程池
ExecutorService service = Executors.newFixedThreadPool(10);
//2. 執(zhí)行指定的線程操作诅挑,需要提供實(shí)現(xiàn)Runnable接口或者Callable接口實(shí)現(xiàn)類的對(duì)象
service.execute(new Number1());//適用于Runnable
service.execute(new Number2());//適用于Runnable
//3. 關(guān)閉連接池
service.shutdown();
}
}