Java進階 ——— Java多執行緒(一)之程序和執行緒
引言
講到執行緒,不可避免的提到程序。而因為執行緒無法脫離程序單獨存在,那什麼是程序?
延伸閱讀,Java多執行緒系列文章
什麼是程序?
程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的最小單位。
例如手機執行的眾多APP,每個可以理解為一個程序(實際上很多APP執行多個程序),每個APP直接互相獨立,互不干擾。
什麼是執行緒?
執行緒:程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位。也就是程式執行的最小單位。
例如優酷APP,我們看視訊的同時還可以快取視訊。看視訊和快取視訊就是執行在程序中的兩個執行緒。
程序和執行緒的關係
程序是一個獨立的空間,一個程序崩潰後,在保護模式下不會對其它程序產生影響,而執行緒只是一個程序中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程序死掉,所以多程序的程式要比多執行緒的程式健壯,但在程序切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒,不能用程序。
- 簡而言之,一個程式至少有一個程序,一個程序至少有一個執行緒
- 執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。
- 另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。
- 執行緒在執行過程中與程序還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
- 從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配。這就是程序和執行緒的重要區別。
舉個不太準確的例子
北京火車站負責北京到上海的鐵路運輸管理。北京火車站就是一個程序。這個程序負責整個線路的排程和分配。而北京到上海的線路,就是執行緒。這個執行緒是真正負責運送旅客和貨物。
為什麼要多執行緒?
現在要從北京運送大量旅客到上海,要在一天全部運送。如果只有一個線路,一輛火車去運送,那肯定是搞不定的,旅客在北京等的都瘋了。
序列
那麼是不是我可以加開多輛火車?然後依次送到上海?理論上是可以的。這種在一條線路上,所有火車依次行駛,就是序列
那如果這個時候火車1出現故障,無法前進,該怎麼辦呢?或者鐵路上只能同時開10輛火車,但是依然承載不了這麼多旅客,一天時間還是運送不完?
並行
既然一條線路運送不了,那我開五條線路,每個線路都可以承載10輛火車,五個線路同時執行。不就可以滿足了嗎?
像上面這樣,在一個程序中開啟多個執行緒執行某個任務,就是多執行緒模式,多個執行緒同時執行,稱為並行
如何開啟多執行緒?
多執行緒的安全問題
像上面這樣,開啟多個執行緒,同時執行,理論上是非常完美的解決辦法。但是這個時候就會出現多執行緒的安全問題。
但是這時候每個執行緒接到通知:在天津站有也有不定量的旅客要乘車去上海。
1.第一條線路的第一輛火車到達天津,如果旅客全部上車了,後面的火車或者其他線路的火車不知道,到了天津站也停了,發現旅客全部上車走了…
2.如果需要三輛火車才能接走全部天津站的旅客,那到底哪幾條線路的哪幾趟火車到天津站停車呢?
3.如果三輛車同時接近天津站,但是天津站站臺每次只能停一輛火車,那誰先進站呢?
當然,這是假想的問題,實際開發工作中,多執行緒的問題遠不止這些,下面用程式碼來演示多執行緒的安全問題。
開啟100個執行緒同時修改成員變數age,並列印值
public class ThreadTest {
private int age = 10;
public void threadTest(){
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new ThreadRunnable());
thread.start();
}
}
class ThreadRunnable implements Runnable {
@Override
public void run() {
age++;
System.out.println(age);
}
}
}
理想狀態下,應該是執行緒依次增加age的值,從11增加到109。
來看下列印的結果
很明顯,這個方法中執行緒並不是安全的,出現這種的原因有很多,最常見的原因就是,當某個執行緒1剛修改age的值,正要列印age的值,這時另一個執行緒2、3進入,又修改了age的值,並且列印結束,這時執行緒1才打印出age的值。
什麼是執行緒安全呢?
簡單理解:如果你的程式碼所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的
或者說:一個類或者程式所提供的介面對於執行緒來說是原子操作或者多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題。執行緒安全問題都是由全域性變數及靜態變數引起的
所以為了保證執行緒安全呢,就需要進行執行緒同步
什麼是執行緒同步?
就是當一個程式對一個執行緒安全的方法或者語句進行訪問的時候,其他的不能再對他進行操作了,必須等到這次訪問結束以後才能對這個執行緒安全的方法進行訪問
如何實現執行緒同步?
那麼如何實現執行緒同步問題呢?下一篇文章我們繼續瞭解如何實現執行緒同步?Java提供了哪些方式實現執行緒同步?
結束
本篇文章主要通過例子講解什麼是程序和執行緒,什麼是多執行緒,什麼是執行緒安全,什麼是執行緒同步問題
感謝
相關推薦
Java進階 ——— Java多執行緒(一)之程序和執行緒
引言 講到執行緒,不可避免的提到程序。而因為執行緒無法脫離程序單獨存在,那什麼是程序? 延伸閱讀,Java多執行緒系列文章 什麼是程序? 程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的最小單位。 例如手機執行的眾多
Java多執行緒和記憶體模型(一):程序和執行緒基礎
Java多執行緒和記憶體模型(一) 由於java是執行在 JVM上 的,所以需要涉及到 JVM 的記憶體模型概念,需要理解記憶體模型,就需要多執行緒的基礎; 而執行緒是基於載體執行緒裡的,所以我們藉由作業系統的程序來講一講。 程序 什麼是程序?
執行緒進階:多工處理(17)——Java中的鎖(Unsafe基礎)
1. 概述 本專題在之前的文章中詳細介紹了Java中最常使用的一種鎖機制——同步鎖。但是同步鎖肯定是不適合在所有應用場景中使用的。所以從本文開始,筆者將試圖通過兩到三篇文章的篇幅向讀者介紹Java中鎖的分類、原理和底層實現。以便大家在實際工作中根據應用場景進行
python-進階教程-多個字典(對映)的合併
0.摘要 當我們處理多個字典(或稱為對映,因為字典是Python中唯一的對映結構),可以通過將多個字典合併為一個字典的方式實現批量處理。 1.ChainMap類 a = {'x': 1, 'z': 3 } b = {'y':
【VMCloud雲平臺進階篇】Monitor監控(一)
qcloud vmcloud終於到了這一篇,從數據層到應用層都是完全基於QCloud平臺優化,完全將微軟系應用架構搬到了國內雲平臺上,也算是國內第一例了。牛皮吹完,說說正事兒,QCloud的監控雖然看起來非常“豐富”:而且似乎沒有統一的監控界面:但實際上能夠支持Windows企業級應用(前幾篇構建的應用架構已
opencv+Python影象處理進階教程學習總結記錄(一)
教程:2 opencv+python影象處理進階 講解老師:賈志剛 1.1 進階主要內容概述:影象卷積與應用,直方圖應用,模板匹配,影象金字塔 1.2 模糊與卷積原理 上圖顯示為一維和二維的均值卷積示例 相關Api : blur 程式碼示例 import c
Windows執行緒(一)最簡單的執行緒建立
一段最簡單的執行緒建立程式碼如下: #include <stdio.h> #include <Windows.h> DWORD WINAPI ThreadFun(LPVOID pM) { printf("子執行緒的執行緒ID號為:%d\n子執行緒輸出
c#多線程(一)——基礎概念和基本使用
err inf nag -c 完成 KS 是否 only () 一、多線程相關的基本概念 進程(Process):是系統中的一個基本概念。 一個正在運行的應用程序在操作系統中被視為一個進程,包含著一個運行程序所需要的資源,進程可以包括一個或多個線程 。進程之間是相對獨立的,
springboot入門(一)檔案配置和執行
使用的eclipse+maven3.1+jdk1.7 pom.xml中的配置: <project xmlns="http://maven.apache.org/POM/4.0.0" xml
Springboot整合dubbo構建maven多模組專案(一)- 專案建立和pom.xml中jar包配置
以前一直用Spring作為容器構建專案,但是看到Spring官網一直在推Springboot,最重要的是Springboot確實避免自己尋找多個jar包(大多數情況下,可能自己都不記得該引入哪些jar包)和jar包之間衝突的問題,同時省掉了在整合其他框架時候
React Native 學習筆記(一)--init 專案 和 執行專案
宣告:此篇blog是在Windows環境下開發Android專案的學習筆記,最近也是在網上翻找資料發現,網上的資源基本上都是Mac環境下的,而且大部分的資料都是關於React Native + Web / Service 的,關於android的學習資源不多,因此也就想通過
Struts2 入門(一) 之 控制器與執行步驟
Struts2是什麼? 是一個MVC框架。框架都是半成品。藉助框架可以提高開發效率。 Filter VS Servlet 過濾器要比Servlet要強大,開發中經常用Servlet作為控制器,Filter也可以作為控制器來使用。 public class ServletDemo implements Serv
Hadoop詞頻統計(一)之叢集模式執行
maven pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLo
精盡MyBatis原始碼分析 - SQL執行過程(一)之 Executor
> 該系列文件是本人在學習 Mybatis 的原始碼過程中總結下來的,可能對讀者不太友好,請結合我的原始碼註釋([Mybatis原始碼分析 GitHub 地址](https://github.com/liu844869663/mybatis-3)、[Mybatis-Spring 原始碼分析 GitHub 地址
版本管理(一)之Git和GitHub的區別(優點和缺點)
機制 最大 客戶 內核 文件 敏捷 star 一定的 sch Git 簡介 https://www.yiibai.com/git/getting-started-git-basics.html Git 是一個開源的分布式版本控制系統,用於敏捷高效地處理任何或小或大的
Linux裝置驅動--塊裝置(一)之概念和框架
基本概念 塊裝置(blockdevice) --- 是一種具有一定結構的隨機存取裝置,對這種裝置的讀寫是按塊進行的,他使用緩衝區來存放暫時的資料,待條件成熟後,從快取一次性寫入裝置或者從裝置一次性讀到緩衝區。 字元裝置(Character device) ---是一個順
Java多執行緒(一)基礎
1.關於執行緒與程序的區別:執行緒指程序中的一個執行場景,也就是執行流程,同一個程序中的執行緒共享其程序中的記憶體和資源(共享的記憶體是堆記憶體和方法區記憶體,棧記憶體不共享,每個執行緒有自己的,一個執行緒一個棧。);每個程序是一個應用程式,都有獨立的記憶體空間。多執行緒的使用是為了提高程式
Java 多執行緒(一)—— 概念的引入
併發和並行 程序和執行緒 如何建立多執行緒 第一種方法:繼承 Thread 類 第二種方法:實現 Runnable 介面 第三種方法:使用匿名內部類建立執行緒 正文 回到頂部 併發和並行 並行:指兩個或多個
深入理解Java多執行緒(一)
關於java多執行緒的概念以及基本用法:java多執行緒基礎 1,停止執行緒 停止執行緒意味著線上程執行完之前停止正在做的操作,即立刻放棄當前的操作,這並不容易。停止執行緒可以用Thread.stop()方法,但是這個方法不安全,所以不建議使用,還有一個方法就是Thre
Java多執行緒(一) 什麼是執行緒
宣告:本系列大多是翻譯自https://www.javatpoint.com,加上自己的增刪改,盡力寫的系統而通俗易懂,後文不再重複宣告。 java的多執行緒是一個同時執行多個執行緒的過程。 執行緒是一個輕量級的子程序,是最小的處理單元。多執行緒和多程序都用於實現多工處理。 但是,我們使用多執