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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程之一:进程与线程

發(fā)布時間:2024/4/13 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程之一:进程与线程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

進程與線程

進程

進程是系統(tǒng)中正在運行的一個程序,程序一旦運行就是進程,也可以說進程是受操作系統(tǒng)管理的基本運行單元進。

平時我們打開的任務管理器中看到進程就是啟動的程序,如瀏覽器的打開等等

?

線程

進程中獨立運行的子任務就是一個線程。像QQ.exe運行的時候就有很多子任務在運行,比如聊天線程、好友視頻線程、下載文件線程等等。

多線程使用的必要性

?若使用得當,線程可以有效地降低程序的開發(fā)和維護等成本,同時提升復雜應用程序的性能。

1、發(fā)揮多核處理器的強大能力

現(xiàn)在,多處理器系統(tǒng)正日益盛行,并且價格不斷降低,即時在低端服務器和中斷桌面系統(tǒng)中,通常也會采用多個處理器,這種趨勢還在進一步加快,因為通過提高時鐘頻率來提升性能已變得越來越困難,處理器生產廠商都開始轉而在單個芯片上放置多個處理器核。試想,如果只有單個線程,雙核處理器系統(tǒng)上程序只能使用一半的CPU資源,擁有100個處理器的系統(tǒng)上將有99%的資源無法使用。多線程程序則可以同時在多個處理器上執(zhí)行,如果設計正確,多線程程序可以通過提高處理器資源的利用率來提升系統(tǒng)吞吐率。

2、在單處理器系統(tǒng)上獲得更高的吞吐率

如果程序是單線程的,那么當程序等待某個同步I/O操作完成時,處理器將處于空閑狀態(tài)。而在多線程程序中,如果一個線程在等待I/O操作完成,另一個線程可以繼續(xù)運行,使得程序能在I/O阻塞期間繼續(xù)運行。

3、建模的簡單性

通過使用線程,可以將復雜并且異步的工作流進一步分解為一組簡單并且同步的工作流,每個工作流在一個單獨的線程中運行,并在特定的同步位置進行交互。我們可以通過一些現(xiàn)有框架來實現(xiàn)上述目標,例如Servlet和RMI,框架負責解決一些細節(jié)問題,例如請求管理、線程創(chuàng)建、負載平衡,并在正確的時候將請求分發(fā)給正確的應用程序組件。編寫Servlet的開發(fā)人員不需要了解多少請求在同一時刻要被處理,也不需要了解套接字的輸入流或輸出流是否被阻塞,當調用Servlet的service方法來響應Web請求時,可以以同步的方式來處理這個請求,就好像它是一個單線程程序。

4、異步事件的簡化處理

服務器應用程序在接受多個來自遠程客戶端的套接字連接請求時,如果為每個連接都分配其各自的線程并且使用同步I/O,那么就會降低這類程序的開發(fā)難度。如果某個應用程序對套接字執(zhí)行讀操作而此時還沒有數(shù)據(jù)到來,那么這個讀操作將一直阻塞,直到有數(shù)據(jù)到達。在單線程應用程序中,這不僅意味著在處理請求的過程中將停頓,而且還意味著在這個線程被阻塞期間,對所有請求的處理都將停頓。為了避免這個問題,單線程服務器應用程序必須使用非阻塞I/O,但是這種I/O的復雜性要遠遠高于同步I/O,并且很容易出錯。然而,如果每個請求都擁有自己的處理線程,那么在處理某個請求時發(fā)生的阻塞將不會影響其他請求的處理。

?

創(chuàng)建線程的方式

創(chuàng)建線程有兩種方式:

1、繼承Thread,重寫父類的run()方法

2、實現(xiàn)Runnable接口。和繼承自THread類差不多,不過實現(xiàn)Runnable后,還是通過一個Thread來啟動。

package main.thread;import java.util.Date;public class ExtendThreadTest {//繼承Thread類static class ThreadDemo extends Thread{public void run(){for(int i = 0; i < 5; i++){System.out.println(Thread.currentThread().getName() + "在運行 ThreadDemo " + new Date());}}}//實現(xiàn)Runnable接口static class RunnableDemo implements Runnable{@Overridepublic void run() {for(int i = 0; i < 5; i++){System.out.println(Thread.currentThread().getName() + "在運行 RunnableDemo " + new Date());}}}public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();threadDemo.start();Thread thread = new Thread(new RunnableDemo());thread.start();//以下代碼只是查看是否不影響子線程的執(zhí)行 // try { // Thread.sleep(5000); // } catch (InterruptedException e) { // e.printStackTrace(); // }for(int i = 0; i < 5 ; i ++){System.out.println(Thread.currentThread().getName() + "在運行 " + new Date());}} }

?

執(zhí)行結果:

main在運行 Fri Jun 21 11:24:05 CST 2019 Thread-0在運行 ThreadDemo Fri Jun 21 11:24:05 CST 2019 Thread-1在運行 RunnableDemo Fri Jun 21 11:24:05 CST 2019 Thread-0在運行 ThreadDemo Fri Jun 21 11:24:05 CST 2019 main在運行 Fri Jun 21 11:24:05 CST 2019 Thread-0在運行 ThreadDemo Fri Jun 21 11:24:05 CST 2019 Thread-1在運行 RunnableDemo Fri Jun 21 11:24:05 CST 2019 Thread-0在運行 ThreadDemo Fri Jun 21 11:24:05 CST 2019 main在運行 Fri Jun 21 11:24:05 CST 2019 Thread-0在運行 ThreadDemo Fri Jun 21 11:24:05 CST 2019 main在運行 Fri Jun 21 11:24:05 CST 2019 Thread-1在運行 RunnableDemo Fri Jun 21 11:24:05 CST 2019 main在運行 Fri Jun 21 11:24:05 CST 2019 Thread-1在運行 RunnableDemo Fri Jun 21 11:24:05 CST 2019 Thread-1在運行 RunnableDemo Fri Jun 21 11:24:05 CST 2019

?

?

看到main線程和Thread-0線程,Thread-0線程交替運行,效果十分明顯。

有可能有些人看不到這么明顯的效果,這也很正常。所謂的多線程,指的是兩個線程的代碼可以同時運行,而不必一個線程需要等待另一個線程內的代碼執(zhí)行完才可以運行。對于單核CPU來說,是無法做到真正的多線程的,每個時間點上,CPU都會執(zhí)行特定的代碼,由于CPU執(zhí)行代碼時間很快,所以兩個線程的代碼交替執(zhí)行看起來像是同時執(zhí)行的一樣。那具體執(zhí)行某段代碼多少時間,就和分時機制系統(tǒng)有關了。分時系統(tǒng)把CPU時間劃分為多個時間片,操作系統(tǒng)以時間片為單位片為單位各個線程的代碼,越好的CPU分出的時間片越小。所以看不到明顯效果也很正常,一個線程打印5句話本來就很快,可能在分出的時間片內就執(zhí)行完成了。所以,最簡單的解決辦法就是把for循環(huán)的值調大一點就可以了(也可以在for循環(huán)里加Thread.sleep方法,這個之后再說)。

/*
* @since JDK1.0
*/
public
class Thread implements Runnable {}
兩種方式采用實現(xiàn)接口Runnable比較好。因為第一,繼承只能單繼承,實現(xiàn)可以多實現(xiàn);第二,實現(xiàn)的方式對比繼承的方式,也有利于減小程序之間的耦合。

線程狀態(tài)

虛擬機中的線程狀態(tài)有六種,定義在Thread.State中:

1、新建狀態(tài)NEW

new了但是沒有啟動的線程的狀態(tài)。比如"Thread t = new Thread()",t就是一個處于NEW狀態(tài)的線程

2、可運行狀態(tài)RUNNABLE

new出來線程,調用start()方法即處于RUNNABLE狀態(tài)了。處于RUNNABLE狀態(tài)的線程可能正在Java虛擬機中運行,也可能正在等待處理器的資源,因為一個線程必須獲得CPU的資源后,才可以運行其run()方法中的內容,否則排隊等待

3、阻塞BLOCKED

如果某一線程正在等待監(jiān)視器鎖,以便進入一個同步的塊/方法,那么這個線程的狀態(tài)就是阻塞BLOCKED

4、等待WAITING

某一線程因為調用不帶超時的Object的wait()方法、不帶超時的Thread的join()方法、LockSupport的park()方法,就會處于等待WAITING狀態(tài)

5、超時等待TIMED_WAITING

某一線程因為調用帶有指定正等待時間的Object的wait()方法、Thread的join()方法、Thread的sleep()方法、LockSupport的parkNanos()方法、LockSupport的parkUntil()方法,就會處于超時等待TIMED_WAITING狀態(tài)

6、終止狀態(tài)TERMINATED

線程調用終止或者run()方法執(zhí)行結束后,線程即處于終止狀態(tài)。處于終止狀態(tài)的線程不具備繼續(xù)運行的能力

?

轉載于:https://www.cnblogs.com/dudu2mama/p/11059918.html

總結

以上是生活随笔為你收集整理的Java多线程之一:进程与线程的全部內容,希望文章能夠幫你解決所遇到的問題。

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