java中实现多线程的三种方式
java中實(shí)現(xiàn)多線程的三種方式
1、實(shí)現(xiàn)多線程的方法:
在java中實(shí)現(xiàn)多線程的兩途徑:繼承Thread類,實(shí)現(xiàn)Runable接口(Callable)2、繼承Thread類實(shí)現(xiàn)多線程:
? 繼承類Thread是支持多線程的功能類,只要?jiǎng)?chuàng)建一個(gè)子類就可以實(shí)現(xiàn)多線程的支持。
所有的java程序的起點(diǎn)是main方法,所以線程一定有自己的起點(diǎn),那這個(gè)起點(diǎn)就是run方法;因?yàn)槎嗑€程的每個(gè)主體類之中必須重寫Thread的run方法。
public void run()這個(gè)run方法沒有返回值,那就說明線程一旦開始就一直執(zhí)行不能返回內(nèi)容。
2.1線程案例:
? 編寫一個(gè)測試線程類繼承Thread 在run方法中寫一個(gè)循環(huán)輸出語句;
分析:創(chuàng)建多個(gè)測試類啟動(dòng)線程,多個(gè)線程回想進(jìn)程一樣,輪流搶占資源,所以多線程程序應(yīng)該是多個(gè)線程彼此交替執(zhí)行;
class TestThread extends Thread{//內(nèi)部類String name;TestThread( String name){this.name=name;}@Overridepublic void run(){for(int i=1;i<10;i++) {System.out.print(name + i);}}}public class MyThread {public static void main(String[] args) {new TestThread("A").run();new TestThread("B").run();new TestThread("C").run();} }上面是調(diào)用Thread的run方法,但是查看日志輸出并不是交替輸出如下
A1A2A3A4A5A6A7A8A9B1B2B3B4B5B6B7B8B9C1C2C3C4C5C6C7C8C9本線程類的功能是進(jìn)行循環(huán)的輸出操作,所有的線程與進(jìn)程是一樣的,都必須輪流去搶占資源,所以多線程的執(zhí)行應(yīng)該是多個(gè)線程彼此交替執(zhí)行,也就是說如果調(diào)用了run方法,那么并不能夠啟動(dòng)多線程,多線程啟動(dòng)的唯一方法是調(diào)用Thread的start方法(調(diào)用此方法執(zhí)行的是run方法體)。
修改如下:
public class MyThread {public static void main(String[] args) {new TestThread("A").start();new TestThread("B").start();new TestThread("C").start();} }運(yùn)行結(jié)果
B1C1A1C2C3B2B3C4A2A3A4A5A6A7A8A9C5C6C7B4B5B6B7B8B9C8C9疑問?為什么多線程的啟動(dòng)不是調(diào)用run方法而必須調(diào)用start方法?
找到j(luò)ava的源代碼:在jdk安裝的目錄找到src壓縮包解壓,在java.lang包里的Thread的start方法如下:
public synchronized void start() {if (threadStatus != 0)throw new IllegalThreadStateException();group.add(this);boolean started = false;try {start0();started = true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}}}private native void start0();在start方法里,開始的地方有IllegalThreadStateException異常拋出,防止線程啟動(dòng)重復(fù)。
? 發(fā)現(xiàn)在start方法里面要調(diào)用一個(gè)start0方法,而且此方法的結(jié)構(gòu)和抽象方法類似,使用了native聲明,在Java開發(fā)里面有一門技術(shù)稱為JNI技術(shù)(Java Native Interface),這門技術(shù)的特點(diǎn):是使用Java調(diào)用本機(jī)操作系統(tǒng)提供的函數(shù)。但是有個(gè)缺點(diǎn):不能夠離開特定的操作系統(tǒng)。
總結(jié):使用Thread類的start方法不僅僅啟動(dòng)多線程的執(zhí)行代碼,還要從不同操作系統(tǒng)中分配資源。
3、實(shí)現(xiàn)Runnable
? Java具有單繼承局限,所有的Java程序針對類的繼承都應(yīng)該是回避,那么線程也一樣,為了解決單繼承的限制,因此才有Runnable接口代碼如下:
@FunctionalInterface public interface Runnable{public void run(); }這個(gè)接口有點(diǎn)特殊是@FunctionalInterface注解修飾的,這是函數(shù)式接口,特征是:一個(gè)接口只有一個(gè)方法。
接口中的方法都是public權(quán)限,不存在默認(rèn)權(quán)限。
使用方法:讓一個(gè)類實(shí)現(xiàn)Runnable接口即可,并且也需要覆寫run()方法。
疑問:但是此接口只有run方法,沒有start方法,怎么啟動(dòng)多線程呢?
不管任何情況下,如果要想啟動(dòng)多線程一定要依靠Thread類完成,在Thread類中有參數(shù)是Runnable參數(shù)的構(gòu)造方法:
- Thread(Runnable target) 接收的是Runnable接口
可以創(chuàng)建一個(gè)參數(shù)是Runnable實(shí)現(xiàn)類的Thread類,調(diào)用start方法啟動(dòng)。
public class MyThread {public static void main(String[] args) {new Thread(new TestThread("A")).start();new Thread(new TestThread("B")).start();new Thread(new TestThread("C")).start();} }總結(jié):實(shí)現(xiàn)Runnable接口來寫多線程的業(yè)務(wù)類,用Thread來啟動(dòng)多線程。
總結(jié)
以上是生活随笔為你收集整理的java中实现多线程的三种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器学习】独立同分布(IID)数据集
- 下一篇: 恢复MAC保存丢失的word文档