日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程调用同一个对象的方法_多线程之如何创建和使用线程

發(fā)布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程调用同一个对象的方法_多线程之如何创建和使用线程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、創(chuàng)建線程和使用線程方式

1.1 繼承Thread

讓線程類繼承自Thread類,然后重寫run(),把需要多線程調(diào)用的代碼放到run()中。但是需要開啟線程的時候不能調(diào)用run方法,而是需要調(diào)用start()方法。

/*** 本類用于演示第一種實(shí)現(xiàn)多線程的方式*/ class MyThread extends Thread{// 需要我們使用多進(jìn)程運(yùn)行的代碼就寫在run方法里@Overridepublic void run() { for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~~" + i);}} } public class ThreadDemo01 extends Thread{public static void main(String[] args) {MyThread thread = new MyThread();thread.start();for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行======" + i);}} }

運(yùn)行結(jié)果:(兩個線程同時運(yùn)行,爭搶cpu,每次執(zhí)行結(jié)果不固定)

12.2 實(shí)現(xiàn)Runnable接口

需要我們創(chuàng)建的線程類實(shí)現(xiàn)Runnable接口。實(shí)現(xiàn)run方法,把需要多線程調(diào)用的代碼寫在run方法中。由于Runnable接口中只有一個run方法,所以不能直接調(diào)用start()。這個時候需要創(chuàng)建一個Thread類的對象來幫助我們開啟線程。創(chuàng)建這個Thread類對象的時候需要將我們的線程類作為參數(shù)傳遞給Thread對象。

/*** 本類用于演示第二種實(shí)現(xiàn)多線程的方式*/ class MyThread2 implements Runnable{// 需要我們使用多進(jìn)程運(yùn)行的代碼就寫在run方法里@Overridepublic void run() { for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~~" + i);}} }public class ThreadDemo02 {public static void main(String[] args) { MyThread2 myThread2 = new MyThread2();// myThread2.run();// 由于Runable接口只有一個run方法,所以實(shí)現(xiàn)Runnable接口的這種方式,線程本身沒有start方法。// 但是必須要調(diào)用start方法才能開啟多線程,所以需要創(chuàng)建Thread類的對象,把我們的線程類作為參數(shù)傳遞給構(gòu)造方法。Thread thread = new Thread(myThread2);thread.start();for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~~" + i);} } }

運(yùn)行結(jié)果:(兩個線程同時運(yùn)行,爭搶cpu,每次執(zhí)行結(jié)果不固定)

2.3 實(shí)現(xiàn)Callable接口

采用實(shí)現(xiàn)Callable接口實(shí)現(xiàn)多線程啟動方式以上兩種的方式不太一樣,下面就看一下怎樣啟動采用實(shí)現(xiàn)Callable接口的線程。

第一步:定義一個類實(shí)現(xiàn)Callable接口,并且指定call()返回值的類型。將業(yè)務(wù)邏輯寫在call()方法中。

第二步:創(chuàng)建FutureTask對象,并將Callable對象傳入FutureTask的構(gòu)造方法中。

第三步:實(shí)例化Thread對象,并在構(gòu)造方法中傳入FurureTask對象。

第四步:啟動線程

/*** 本類用于演示第三種實(shí)現(xiàn)多線程的方式*/ class MyCallable implements Callable<String>{@Overridepublic String call() throws Exception {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~" + i);}return "MyCallable接口執(zhí)行完成!";} } public class ThreadDemo03 {public static void main(String[] args) throws Exception {// 1、創(chuàng)建FutureTask實(shí)例,創(chuàng)建MyCallable實(shí)例FutureTask<String> futureTask = new FutureTask<>(new MyCallable());// 2、創(chuàng)建Thread實(shí)例,來執(zhí)行futureTaskThread thread = new Thread(futureTask);thread.start();// 3、主線程for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~" + i);}// 4、獲取執(zhí)行結(jié)果System.out.println(futureTask.get());} }

運(yùn)行結(jié)果:

1.4 線程池

在一個應(yīng)用程序中,我們需要多次使用線程,也就意味著,我們需要多次創(chuàng)建并銷毀線程。而創(chuàng)建并銷毀線程的過程勢必會消耗內(nèi)存。而在Java中,內(nèi)存資源是及其寶貴的,所以,我們就提出了線程池的概念。

線程池:Java中開辟出了一種管理線程的概念,這個概念叫做線程池,從概念以及應(yīng)用場景中,我們可以看出,線程池的好處,就是可以方便的管理線程,也可以減少內(nèi)存的消耗。

那么,我們應(yīng)該如何創(chuàng)建一個線程池那?Java中已經(jīng)提供了創(chuàng)建線程池的一個類:Executor而我們創(chuàng)建時,一般使用它的子類:ThreadPoolExecutor。

第一步:使用Executors獲取線程池對象;

第二步:通過線程池獲取對象獲取線程并執(zhí)行Runable子類實(shí)例;

class MyThread4 implements Runnable{// 需要我們使用多進(jìn)程運(yùn)行的代碼就寫在run方法里@Overridepublic void run() { for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~~" + i);}} } public class ThreadDemo04 {public static void main(String[] args) { // 第一步:使用Executors獲取線程池對象;ExecutorService executorService = Executors.newFixedThreadPool(10);// 第二步:通過線程池獲取對象獲取線程并執(zhí)行Runable實(shí)例;executorService.execute(new MyThread4()); for (int i = 1; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "線程正在運(yùn)行~~~~~~" + i);} } }

運(yùn)行結(jié)果:

二、總結(jié)

2.1 實(shí)現(xiàn)接口和繼承Thread類比較

(1)接口更適合多個相同的程序代碼的線程去共享同一個資源。

實(shí)現(xiàn)Runnable接口這種方式,可以把多線程之間相同的操作放到一個Runnable接口的run方法中實(shí)現(xiàn),然后可以通過多個thread來執(zhí)行同一個Runnable實(shí)例。可以達(dá)到在一個地方開發(fā),多個地方使用,做到代碼的復(fù)用。

(2)接口可以避免Java中單繼承的局限性。

Java的設(shè)計(jì)是單繼承的設(shè)計(jì),如果采用繼承Thread的方式實(shí)現(xiàn)多線程,則不能繼承其他的類,就會錯失繼承很多父類方法。

(3)接口代碼可以被多個線程共享,代碼和線程獨(dú)立。

(4)線程池只能放入實(shí)現(xiàn)Runnable或Callable接口的線程,不能直接放入繼承Thread的類。

2.2 Runnable和Callable接口比較

A、相同點(diǎn):

(1)兩者都是接口;

(2)都可以用來編寫多線程程序;

(3)兩者都需要調(diào)用Thread.start()啟動線程;

B、不同點(diǎn):

(1)實(shí)現(xiàn)Callable接口的線程能返回執(zhí)行結(jié)果;而實(shí)現(xiàn)Runnable接口的線程不能返回結(jié)果;若需要用這個線程執(zhí)行任務(wù),不需要控制則建議使用Runnable,若需要動態(tài)監(jiān)控任務(wù)則建議使用Callable。

(2)Callable接口的call()方法允許拋出異常;而Runnable接口的run()方法不允許拋異常。

(3)實(shí)現(xiàn)Callable接口的線程可以調(diào)用Future.cancel取消執(zhí)行,而實(shí)現(xiàn)Runnable接口的線程不能。

注意點(diǎn):Callable接口支持返回執(zhí)行結(jié)果,此刻需要調(diào)用FutureTask.get()方法實(shí)現(xiàn),此方法會阻塞主線程直到獲取“將來”結(jié)果;不調(diào)用此方法時,主線程不會阻塞。只能在不需要并發(fā)的地方調(diào)用get()方法。

總結(jié)

以上是生活随笔為你收集整理的多线程调用同一个对象的方法_多线程之如何创建和使用线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。