多線程調用同一個對象的方法_多線程之如何創建和使用線程

e5a152ebb9d6fbde7f7eea0373ff640d.png

一、創建線程和使用線程方式

1.1 繼承Thread

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

/***  本類用于演示第一種實現多線程的方式*/
class MyThread extends Thread{// 需要我們使用多進程運行的代碼就寫在run方法里@Overridepublic void run() {		for (int i = 1; i < 5; i++) {	System.out.println(Thread.currentThread().getName() + "線程正在運行~~~~~~" + 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() + "線程正在運行======" + i);}}
}

運行結果:(兩個線程同時運行,爭搶cpu,每次執行結果不固定)

095324984285411420146f60baf28e6b.png

12.2 實現Runnable接口

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

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

運行結果:(兩個線程同時運行,爭搶cpu,每次執行結果不固定)

de0feecec466505cd78dd1addde3f48b.png

2.3 實現Callable接口

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

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

第二步:創建FutureTask對象,并將Callable對象傳入FutureTask的構造方法中。

第三步:實例化Thread對象,并在構造方法中傳入FurureTask對象。

第四步:啟動線程

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

運行結果:

18167ebcc76461795e4b68d46fd1b842.png

1.4 線程池

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

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

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

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

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

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

運行結果:

99d99d14bee9d16ec1a7e365a94ff7f2.png

二、總結

2.1 實現接口和繼承Thread類比較

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

實現Runnable接口這種方式,可以把多線程之間相同的操作放到一個Runnable接口的run方法中實現,然后可以通過多個thread來執行同一個Runnable實例。可以達到在一個地方開發,多個地方使用,做到代碼的復用。

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

Java的設計是單繼承的設計,如果采用繼承Thread的方式實現多線程,則不能繼承其他的類,就會錯失繼承很多父類方法。

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

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

2.2 Runnable和Callable接口比較

A、相同點:

(1)兩者都是接口;

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

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

B、不同點:

(1)實現Callable接口的線程能返回執行結果;而實現Runnable接口的線程不能返回結果;若需要用這個線程執行任務,不需要控制則建議使用Runnable,若需要動態監控任務則建議使用Callable。

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

(3)實現Callable接口的線程可以調用Future.cancel取消執行,而實現Runnable接口的線程不能。

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457626.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457626.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457626.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

struts2的namespace的問題

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <inc…

JS_16閉包

閉包 什么是閉包 理解1&#xff1a;閉包是嵌套的內部函數理解2&#xff1a;閉包是包含被引用變量&#xff08;函數&#xff09;的對象 閉包產生的條件 函數嵌套子函數調用了父函數的數據父函數被調用了&#xff08;子函數不一定需要被調用&#xff0c;只需要執行函數定義即可&…

[Intel Edison開發板] 02、Edison開發板入門

一、前言 Start from the link: 開始學習的鏈接 上面鏈接是官網的教程&#xff0c;按照教程可以開發板入門&#xff1a; 其中第一步是了解開發板&#xff0c;涉及到如何組裝、如何連線、一些主要的接口簡單介紹等信息&#xff1b;第二步主要是介紹如何用官方提供的工具進行配置…

python apscheduler一次只有一個job_Python使用APScheduler實現定時任務過程解析

前言APScheduler是基于Quartz的一個Python定時任務框架。提供了基于日期、固定時間間隔以及crontab類型的任務&#xff0c;并且可以持久化任務。一、安裝APSchedulerpip install apscheduler二、基本概念APScheduler有四大組件&#xff1a;1、觸發器 triggers &#xff1a;觸發…

java web service簡單示例

http://www.iteye.com/topic/1135747 轉載于:https://www.cnblogs.com/fycct/p/5669420.html

shell統計指定目錄下所有文件類型及數量

#!/bin/bash#Synopsis:用于統計腳本當前所在目錄或者用戶指定目錄下的所有文件類型及數量#若直接運行腳本而不接任何命令行參數,則默認會統計腳本所在目錄下的文件#Date:2016/10#Author:Jian#Usage:sh fileStat.sh /path1 /path2testFile$(mktemp /tmp/testfile.XXX)#如果沒有指…

python cross val score_sklearn函數:cross_val_score(交叉驗證評分)

sklearn.model_selection.cross_val_score(estimator,X,yNone,*,groupsNone,scoringNone,cvNone,n_jobsNone,verbose0,fit_paramsNone,pre_dispatch2*n_jobs,error_scorenan)前面我們提到了4種分割數據集的方法&#xff0c;在分割完數據集后&#xff0c;我們訓練模型&#xff0…

JS_17 ES5,ES6

ES5 嚴格模式 定義方法 use strict特性&#xff1a; 必須使用var定義變量存在eval作用域禁止自定義函數中的this指向window對象不能有重名屬性 JSON對象 json.stringify(obj/arr):js對象轉換為json對象json.parse(str):json對象轉換為js對象 Object拓展 Object.create(p…

幾種純css布局的導航欄

1.垂直導航欄 頁面效果 <ul class"nav"><li><a href"home.htm">Home</a></li><li><a href"about.htm">About</a></li><li><a href"services.htm">Services</a&…

python中函數的參數傳遞(傳值還是傳引用)

函數的參數傳遞 函數參數傳遞有兩種方式&#xff0c;傳值和傳引用&#xff0c;傳值只是把變量的值復制一份給了實參&#xff0c;函數內部的操作不會改變函數外部變量的值&#xff0c;而傳引用傳遞的是外部變量的地址&#xff0c;函數內部直接操作函數外部變量的儲存空間&#…

poi獲取有效單元格個數_EXCEL利用SUM函數和FREQUENCY函數數組公式統計不同區間數據個數...

EXCEL函數公式大全之利用FREQUENCY函數數組公式統計不同區間數據個數。EXCEL函數與公式在工作中使用非常的頻繁&#xff0c;會不會使用公式直接決定了我們的工作效率&#xff0c;今天我們來學習一下提高我們工作效率的函數FREQUENCY函數和數組公式。今天我們的例子是統計學生在…

windows安裝rsync

客戶端&#xff1a;cwRsync 4.0.5 Installer服務端&#xff1a;cwRsyncServer 4.0.5 Installer 安裝配置Rsync服務端 1.直接雙擊安裝包安裝即可&#xff0c;在安裝過程中會有要求用戶輸入賬戶密碼或者使用默認。此賬戶是rsync服務運行的用戶。 2.安裝完成之后&#xff0c;進入程…

洛谷 P2735 電網 Electric Fences Label:計算幾何--皮克定理

題目描述 在本題中&#xff0c;格點是指橫縱坐標皆為整數的點。 為了圈養他的牛&#xff0c;農夫約翰&#xff08;Farmer John)建造了一個三角形的電網。他從原點&#xff08;0,0&#xff09;牽出一根通電的電線&#xff0c;連接格點(n,m)&#xff08;0<n<32000,0<m&l…

Python元類(type()和metaclass)

1. 元類是什么 眾所周知&#xff0c;對象由類實例化而來&#xff0c;類是對象的模板&#xff0c;而python一切皆對象&#xff0c;類也是對象&#xff0c;它由元類&#xff08;type&#xff09;創建&#xff0c;所以元類是類的類&#xff0c;是類的模板 2. 創建類的另一種方法…

word文檔打印 自動編碼_辦公室文件打印有哪些技巧 辦公室文件打印技巧介紹【圖文】...

辦公室文件打印實用技巧三則一. 打印文件直接裝訂——逆序打印相信使用Word打印過長篇文檔的朋友一定都清楚&#xff0c;打印完成后的裝訂一直是個麻煩事兒&#xff0c;因為文件由打印機打出時&#xff0c;第一頁肯定會在最下面&#xff0c;裝訂之前總要費時費力的把紙張按順序…

Strategy 策略模式

意圖 定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。 動機 策略模式為了適應不同的需求&#xff0c;只把變化點封裝了&#xff0c;這個變化點就是實現不同需求的算法&#xff0c;但是&#xff0c;用戶需要知道各種…

python 消息中間件_消息隊列中間件 RabbitMQ 詳細介紹——安裝與基本應用(Python)...

RabbitMQ 是當前最流行的消息中間件(Message Broker)之一&#xff0c;支持多種消息協議(如 AMQP、MQTT)。同時它也是一個輕量級的非常易于部署的開源軟件&#xff0c;可以運行在當前大多數操作系統及云端環境中&#xff0c;也能夠部署在分布式的集群環境里以達到高可用、可伸縮…

用 Flask 來寫個輕博客 (1) — 創建項目

目錄 目錄前言擴展閱讀部署開發環境創建 Github 項目前言 一步一步的實現一個 Flask 輕博客項目啟動&#xff0c;最新的代碼會上傳到 Github。 擴展閱讀 歡迎使用 Flask — virtualenv 部署開發環境 連接 GitHubhostnamectl set-hostname flask-dev # 設置 hostname ssh-keyg…

python靜態方法,類方法,屬性方法,實例方法

DAY 3. 靜態方法&#xff0c;類方法&#xff0c;屬性方法&#xff0c;實例方法 有四種方法&#xff0c;實例方法&#xff0c;類方法&#xff0c;靜態方法&#xff0c;屬性方法 實例方法 實例方法的第一個參數是self&#xff0c;他會指向類的實例化對象&#xff0c;只能被對象…

ubuntu 軟件包降級

ubuntu 軟件包降級 sudo aptitude install libssl-dev 1. 是否接受該解決方案&#xff1f; [Y/n/?] n 2. 是否接受該解決方案&#xff1f; [Y/n/?] y 3. 您要繼續嗎&#xff1f; [Y/n/?] ysudo aptitude install libcairo21.4.10-1ubuntu4 # 強制降級 sudo aptitude forbid…