跳到主要內容

Java Process And Thread 筆記

英文很差,所以附上原文。

關係大概是這樣吧

image-55

Processes And Threads

Processes (進程)

每個 Process 都可視為一個獨立運作的環境,有自己完整、私有的 Run-Time 資源,特別是每個 process 都有自己的記憶體空間。

Processes 聽起來很像 programs 或 application 的另一種說法,然而事實上一個 application 有可能是許多 processes 合作組成的。為了讓 processes 彼此互相合作,一些作業系統支援了 Inter Process Communication (IPC) resources,例如 pipes 與 sockets。IPC 不只讓不同的 processes 互相通訊,同時也支援不同系統的 pocesses 互相通訊。

大部分 JVM 實現的都是 single process。Java Application 可以創建額外的 process 透過 ProcessBuilder Object。

A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.
Processes are often seen as synonymous with programs or applications. However, what the user sees as a single application may in fact be a set of cooperating processes. To facilitate communication between processes, most operating systems support Inter Process Communication (IPC) resources, such as pipes and sockets. IPC is used not just for communication between processes on the same system, but processes on different systems.
Most implementations of the Java virtual machine run as a single process. A Java application can create additional processes using a ProcessBuilder object. Multiprocess applications are beyond the scope of this lesson.

Threads (線程)

Thread 在某些時候被視為一種輕量的 processes (lightweight processes),與 processes 一樣,threads 也提供了一個可執行的環境。但相對於 processes 創建時,threads 並不需要太多的資源。

每個 process 最少都有一個 thread,threads 共享 processs 上的資源,包含 memory 與 files。這樣使得效率提高,但相對的也產生了一些潛在的問題,比如說 Race-condition 之類的問題。

Multithreaded 是 Java 平台上重要的一個特徵,每個 application 最少會有一個 thread。如果你去計算 "System" 上的 threads ,他們做的事情相似於記憶體管理或一些信號處理。但在這裡,我們只需要先認識 Main Thread,因為它能夠去創建額外的 threads。

Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.
Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files. This makes for efficient, but potentially problematic, communication.
Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread — or several, if you count "system" threads that do things like memory management and signal handling. But from the application programmer's point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads, as we'll demonstrate in the next section.

使用時機

  1. IO bound task,避免 IO blocking 的阻塞。
  2. CPU bound task,避免長時間大運算的邏輯的阻塞,藉由 threads 的使用,有效率地利用 CPU 。
  3. Schedule,ScheduledThreadPoolExecutor 會用到 threads
  4. Daemon,daemon 是一種在 backgrouopd 運作的 thread,當所有的 non-daemon 都結束了,daemon 就會自動終止。另外從 daemon 裡面建立出來的 thread 也都會歸類在 daemon-thread。

Life cycle

image-7

圖片來自:https://github.com/JustinSDK/JavaSE6Tutorial/blob/master/docs/CH15.md#1514-執行緒生命周期

Synchonized 同步

public synchronized void myMethod() {
    //code
}

synchonized 用來保證一次只會有一個 thread 對某個資源的存取權,多執行緒對相同的 Object 做存取時,會發生:

DeadLock

比較經典的例子,哲學家吃飯
https://www.tutorialspoint.com/java/java_thread_deadlock.htm

Race Condition

比較經典的例子,應該就是提款機、賣票。
A 帳戶同時間發生, user1 與 user2 匯款,如果沒有 synchonized 的處理,會有

  1. user1 與 user2 都匯款成功, save
  2. user1 與 user2 都匯款成功, user2 的匯款資料蓋過 user1 , 損失 user1 的匯款金額。
  3. user1 與 user2 都匯款成功, user1 的匯款資料蓋過 user2 , 損失 user2 的匯款金額。

這個網誌中的熱門文章

Parse URI query string to Key Value

Parse URI query String to Map 做 urlDecode 處理 沒有任何 query String 回傳 Empty Map 確保只處理 key-value 結構的 query String package com.example.util; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.utils.URIBuilder; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; /** * Created by jerry on 2017/12/28. * * @author jerry */ @Slf4j public class UriUtil { private UriUtil() { } public static Map splitQuery(final String uri) { Map queryPairs = new LinkedHashMap (); try { final URI uri = new URIBuilder(uri).build(); final String rawQuery = uri.getRawQuery(); log.info("CurrentUrl Query: {}", rawQuery); // 過濾沒有 query string // 還有過濾無法成對 keyValue 的 query, e.g. http://host/path?123 if (Objects.isNull(rawQuery) |...

Spring-boot Thymeleaf Html5 SAXParseException 解析錯誤

thymeleaf 解析 html5 出錯 <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>SB Admin - Start Bootstrap Template</title> <!-- Bootstrap core CSS--> <link href="../static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom fonts for this template--> <link href="../static/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> <!-- Page level plugin CSS--> <link href="../static/vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet"> <!-- Custom styles for this template--> <li...

Google Compute Engine‎ - AccessDeniedExceptions 403

原因 打算從 instance 打包 logs 到 google cloud storage 發生了 AccessDeniedException: 403 Insufficient OAuth2 scope to perform this operation. , 看起來是 instance 沒有 storage 權限 解決 Reference: https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes 重新設定 service account 權限 instance 上內建有 gcloud , 就直接用現有的工具查詢一下 instance 的 account. $ gsutil info 或者在本機直接 gcloud compute instances describe INSTANCE_NAMES Account: [alpha-number-compute@developer.gserviceaccount.com] Project: [our-project-name] 會看到 instance 的一些狀態, 接下來就簡單多了, 按照下列的說明, 要先 stop instance, 更改 storage scope 再重新 start 。 To change an instance's service account and access scopes, the instance must be temporarily stopped. To stop your instance, read the documentation for Stopping an instance. After changing the service account or access scopes, remember to restart the instance. # Stop Instance gcloud compute instances stop INSTANCE_NAMES # 設定 storage scope 為 full (Read, Write) gcloud co...