进程和线程的关系与区别是什么?如何创建多线程?
單核CPU和多核CPU:
單核CPU:在一個時間單元內,只能執行一個線程的任務。是一種假的多線程。(單核CPU可以“掛起”一個線程,執行另一個線程,看起來像是多線程)
多核CPU:多線程。
一個Java應用程序java.exe,至少有三個線程:main()主線程,gc()垃圾回收線程,異常處理線程。如果發生異常,會影響主線程。
并行和并發:
并行:多個CPU同時執行多個任務。比如:多個人同時做不同的事。
并發:一個CPU(采用時間片)"同時"執行多個任務。比如:秒殺,多個人做同一件事。
注:“同時”:其實是采用時間片的方式,執行一段A,再執行一段B,只不過時間比較短,看起來就像是同時進行一樣。
進程與線程
程序(program):是為完成特定任務、用某種語言編寫的一組指令的集合。即指一段靜態的代碼,靜態對象。
**進程(process):**是程序的一次執行過程,或是正在運行的一個程序。是一個動態的過程,有自身的產生、存在和消亡的過程。–生命周期
進程是資源分配的單位,系統在運行時為每個進程分配不同的內存區域。
**線程(thread):**進程可進一步細化為線程,是一個程序內部的一條執行路徑。
線程作為調度和執行的單位,每個線程擁有獨立的運行棧和程序計數器(pc),線程切換開銷小;
一個進程中的多個線程共享相同的內存單元/內存地址空間,它們從同一堆中分配對象,可以訪問相同的變量和對象。這就使得線程間通信更簡便、高效。但多個線程操作共享的系統資源可能會帶來安全隱患。
進程和線程的關系:
1.一個進程至少有一個線程,可以包括多個線程,而一個線程只能屬于一個進程。
2.一個進程中的多個線程共享該進程的內存空間即方法區和堆空間。
2.一個進程的崩潰在保護模式下不會對其他進程產生影響,但是一個線程崩潰會影響整個進程死掉。多進程的程序要比多線程的程序健壯性更強。
進程和線程的區別:
1.根本區別:進程是操作系統資源分配的基本單位;
線程是處理器任務調度和執行的基本單位。
2.資源開銷:每個進程都有獨立的代碼可數據空間,程序之間的切換會產生較大的開銷;
線程是輕量級的進程,線程共享代碼可數據空間,每個線程都有自己獨立的運行棧和程序計數器(pc),線程切換開銷小;
3.內存分配:系統在運行時為每個進程分配不同的內存區域;
而一個進程中的多個線程共享相同的內存單元/內存地址空間。
4.所處環境:在操作系統中可以同時運行多個進程,在一個進程中可以有多個線程同時執行。
5.執行過程:進程有程序運行的入口、順序執行序列及程序出口;而線程不能獨立運行,必須依賴于進程中。
6.包含關系:線程是進程的一部分,被稱為輕量級進程。
-----------------------------------------------分割線------------------------------------------------------------
多線程的優點:
1.提高應用程序的響應,對圖形化界面更有意義,可增強用戶體驗。
2.提高計算機系統CPU的利用率。
3.改善程序結構。將既長又復雜的進程分為多個線程,獨立運行,利于理解和修改。
什么時候需要多線程?
1.程序需要同時執行兩個或多個任務。
2.程序需要實現一些等待的任務時,比如用戶輸入、文件讀寫操作、網絡操作、搜索燈。
3.需要一些后臺運行的程序時。
線程的創建和啟動:
java語言的JVM允許程序運行多個線程,它通過java.lang.Thread類來體現。
Thread類的特性:
1.每個線程都是通過某個特定Thread對象的run()方法來完成操作的,經常把run()方法的主題稱為線程體。
2.通過該Thread對象的start()方法來啟動這個線程,而非直接調用run().
Thread類的相關常用方法:
1.start():啟動當前線程;調用當前線程的run();
2.run():通常需要重寫Thread類中的此方法,將創建的線程要執行的操作聲明在此方法中;
3.currentThread():靜態方法:返回執行當前代碼的線程;
4.getName():獲取當前線程的名字;
5.setName():設置當前線程的名字;
6.yield():釋放當前CPU的執行權;
7.join():在線程A中調用線程B的join(),此時線程A就進入阻塞狀態,直到線程B完全執行完以后,線程A才結束阻塞狀態;
8.stop():已過時。當執行此方法時,強制結束當前線程;
9.sleep(long millitime):讓當前線程睡眠指定的的millitime毫秒。在指定的millitime時間內,當前線程是阻塞狀態;
10.isAlive():判斷當前線程是否存活。
線程的優先級:
1.MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
2.如何獲取和設置當前線程的優先級?
getPriority():獲取線程的優先級
setPriority(int p):設置線程的優先級
tips:高優先級的線程要搶占低優先級線程CPU的執行權,但是從概率上講,高優先級的線程高概率下會先被執行。
并不意味這只有當高優先級的線程執行完以后,低優先級的線程才會執行。
---------------------------------------------分割線----------------------------------------------------------------------------------------
多線程的創建
方式一:繼承thread類
1.創建一個繼承于thread類的子類;
2.重寫thread類的run()–>將此線程執行的操作聲明在run()中;
3.創建thread類的子類對象;
4.通過此對象調用start():①啟動當前線程;②調用當前線程的run().
eg:
子類MyThread Code:
Test Code:
public class ThreadTest {public static void main(String[] args) {//3.創建thread類的子類對象//main()的主線程 調用t1對象MyThread t1 = new MyThread(); //alt + Enter//4.通過此對象調用start():①啟動當前線程;②調用當前線程的run()t1.start();//調用start(),執行run()之后,t1的分線程執行//tips1:啟動一個線程,必須調用start(),不能通過直接調用run()的方式啟動線程。//t1.run();//相當于只是在main()中調用run方法,并不是Thread中的run(),沒有啟動分線程//tips2:如果再啟動一個線程,必須重新創建一個Thread子類的對象,調用此對象的start();遍歷100以內的偶數,不可以還讓已經start()的線程去執行,會報 java.lang.IllegalThreadStateException // t1.start();//需要重新創建一個線程的對象MyThread t2 = new MyThread();t2.start();//仍然在main線程中執行,線程交互for (int i = 0; i < 100; i++) {if(i % 2 == 0){System.out.println(Thread.currentThread().getName()+ ":" + i + "******main()****************");}}} }tips1:啟動一個線程,必須調用start(),不能通過直接調用run()的方式啟動線程。
tips2:如果再啟動一個線程,必須重新創建一個Thread子類的對象,調用此對象的start();
創建多線程的方式二:實現Runnable接口
1.創建一個實現了Runnable接口的類;
2.實現類去實現Runnable中的抽象方法:run();
3.創建實現類的對象;
4.將此對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象;
5.通過Thread類的對象調用start();
比較創建多線程的兩種方式:
開發中我們優先選擇:實現Runnable接口的方式;
原因:1.實現的方式沒有類的單繼承性的局限性;
2.實現的方式更適合來處理多個線程有共享數據的情況.
聯系:public Thread implements Runnable{} Thread類本身實現了Runnable接口;
相同點:兩種方式都需要重寫run(),將線程要執行的邏輯聲明在run()中.
啟動線程都是調用Thread類中的start().
eg:創建三個窗口賣票,總票數100張,使用繼承Thread類的方式
class Window extends Thread{ // private int ticket = 100;//修改窗口1的票數,窗口2/3的沒變private static int ticket = 100;//應該改為static,三個線程共享一個@Overridepublic void run() {while(true){if(ticket > 0){ // System.out.println(Thread.currentThread().getName());System.out.println(getName()+"賣票,票號為:"+ticket);ticket--;}else{break;}}} }public class WindowTest {public static void main(String[] args) {Window w1 = new Window();Window w2 = new Window();Window w3 = new Window();//得new三個對象w1.setName("窗口1");w2.setName("窗口2");w3.setName("窗口3");//三個對象分別調用setName();w1.start();w2.start();w3.start();} }創建三個窗口賣票,總票數100張,使用實現Runnable接口的方式;
class Window1 implements Runnable{private int ticket = 100;//不用加static,本身共享數據@Overridepublic void run() {while (true) {if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "賣票:票號為" + ticket);ticket--;} else {break;}}} }public class WindowTest1 {public static void main(String[] args) {Window1 w = new Window1(); // Window1 w2 = new Window1(); // Window1 w3 = new Window1();沒必要new三個對象Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);//三個線程共享一個new出來的對象t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();} }總結
以上是生活随笔為你收集整理的进程和线程的关系与区别是什么?如何创建多线程?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux dig
- 下一篇: hadoop--集群时间同步(可不同步)