執行緒、多執行緒和執行緒池面試專題
極力推薦文章:歡迎收藏
Android 乾貨分享
閱讀五分鐘,每日十點,和您一起終身學習,這裡是程式設計師Android
本篇文章主要介紹 Android
開發中的部分知識點,通過閱讀本篇文章,您將收穫以下內容:
1、開啟執行緒的三種方式?
1)繼承Thread
類,重寫run()
方法,在run()
方法體中編寫要完成的任務 new Thread().start();
2)實現Runnable
介面,實現run()
方法 new Thread(new MyRunnable()).start();
3)實現Callable
介面MyCallable
類,實現call()
方法,使用FutureTask
Callable
物件,使用FutureTask
物件作為Thread
物件的target
建立並啟動執行緒;呼叫FutureTask
物件的get()
方法來獲得子執行緒執行結束後的返回值。
FutureTask<Integer> ft = new FutureTask<Integer>(new MyCallable());
new Thread(ft).start();
2、run()和start()方法區別
run()
方法只是執行緒的主體方法,和普通方法一樣,不會建立新的執行緒。
只有呼叫start()
方法,才會啟動一個新的執行緒,新執行緒才會呼叫run()
方法,執行緒才會開始執行。
3、如何控制某個方法允許併發訪問執行緒的個數?
建立Semaphore
變數,Semaphore semaphore = new Semaphore(5, true);
當方法進入時,請求一個訊號,如果訊號被用完則等待,方法執行完,釋放一個訊號,釋放的訊號新的執行緒就可以使用。
4、在Java中wait和seelp方法的不同
wait()
方法屬於Object
類,呼叫該方法時,執行緒會放棄物件鎖,只有該物件呼叫notify()
方法後本執行緒才進入物件鎖定池準備獲取物件鎖進入執行狀態。
sleep()
方法屬於Thread
類,sleep()
導致程式暫停執行指定的時間,讓出CPU
,但它的監控狀態依然儲存著,當指定時間到了又會回到執行狀態,sleep()
5、談談wait/notify關鍵字的理解
notify:
喚醒在此物件監視器上等待的單個執行緒
notifyAll():
通知所有等待該競爭資源的執行緒
wait:
釋放obj
的鎖,導致當前的執行緒等待,直接其他執行緒呼叫此物件的notify()
或notifyAll()
方法
當要呼叫wait()
或notify()/notifyAll()
方法時,一定要對競爭資源進行加鎖,一般放到synchronized(obj)
程式碼中。當呼叫obj.notify/notifyAll
後,呼叫執行緒依舊持有obj
鎖,因此等待執行緒雖被喚醒,但仍無法獲得obj
鎖,直到呼叫執行緒退出synchronized
塊,釋放obj
鎖後,其他等待執行緒才有機會獲得鎖繼續執行。
6、什麼導致執行緒阻塞?
(1)一般執行緒阻塞
1)執行緒執行了Thread.sleep(int millsecond)
方法,放棄CPU
,睡眠一段時間,一段時間過後恢復執行;
2)執行緒執行一段同步程式碼,但無法獲得相關的同步鎖,只能進入阻塞狀態,等到獲取到同步鎖,才能恢復執行;
3)執行緒執行了一個物件的wait()
方法,直接進入阻塞態,等待其他執行緒執行notify()/notifyAll()
操作;
4)執行緒執行某些IO
操作,因為等待相關資源而進入了阻塞態,如System.in
,但沒有收到鍵盤的輸入,則進入阻塞態。
5)執行緒禮讓,Thread.yield()
方法,暫停當前正在執行的執行緒物件,把執行機會讓給相同或更高優先順序的執行緒,但並不會使執行緒進入阻塞態,執行緒仍處於可執行態,隨時可能再次分得CPU
時間。執行緒自閉,join()
方法,在當前執行緒呼叫另一個執行緒的join()
方法,則當前執行緒進入阻塞態,直到另一個執行緒執行結束,當前執行緒再由阻塞轉為就緒態。
6)執行緒執行suspend()
使執行緒進入阻塞態,必須resume()
方法被呼叫,才能使執行緒重新進入可執行狀態。
7、執行緒如何關閉?
1) 使用標誌位
2)使用stop()
方法,但該方法就像關掉電腦電源一樣,可能會發生預料不到的問題
3)使用中斷interrupt()
public class Thread {
// 中斷當前執行緒
public void interrupt();
// 判斷當前執行緒是否被中斷
public boolen isInterrupt();
// 清除當前執行緒的中斷狀態,並返回之前的值
public static boolen interrupted();
}
但呼叫interrupt()
方法只是傳遞中斷請求訊息,並不代表要立馬停止目標執行緒。
8、講一下java中的同步的方法
之所以需要同步,因為在多執行緒併發控制,當多個執行緒同時操作一個可共享的資源時,如果沒有采取同步機制,將會導致資料不準確,因此需要加入同步鎖,確保在該執行緒沒有完成操作前被其他執行緒呼叫,從而保證該變數的唯一一性和準確性。
1)synchronized修飾同步程式碼塊或方法
由於java
的每個物件都有一個內建鎖,用此關鍵字修飾方法時,內建鎖會保護整個方法。在呼叫該方法前,需獲得內建鎖,否則就處於陰塞狀態。
2)volatile修飾變數
保證變數線上程間的可見性,每次執行緒要訪問volatile
修飾的變數時都從記憶體中讀取,而不快取中,這樣每個執行緒訪問到的變數都是一樣的。且使用記憶體屏障。
3)ReentrantLock重入鎖,它常用的方法有ReentrantLock():
建立一個ReentrantLock
例項
lock()
獲得鎖unlock()
釋放鎖
4)使用區域性變數ThreadLocal實現執行緒同步
每個執行緒都會儲存一份該變數的副本,副本之間相互獨立,這樣每個執行緒都可以隨意修改自己的副本,而不影響其他執行緒。常用方法ThreadLocal()
建立一個執行緒本地變數;get()
返回此執行緒區域性的當前執行緒副本變數;initialValue()
返回此執行緒區域性變數的當前執行緒的初始值;set(T value)
將此執行緒變數的當前執行緒副本中的值設定為value
5) 使用原子變數
如AtomicInteger
,常用方法AtomicInteger(int value)
建立個有給定初始值的AtomicInteger
整數;addAndGet(int data)
以原子方式將給定值與當前值相加
6)使用阻塞佇列實現執行緒同步
例如LinkedBlockingQueue<E>
9、如何保證執行緒安全?
執行緒安全性體現在三方法:
1)原子性:
提供互斥訪問,同一時刻只能有一個線和至資料進行操作。
JDK
中提供了很多atomic
類,如AtomicInteger\AtomicBoolean\AtomicLong
,它們是通過CAS
完成原子性。
JDK
提供鎖分為兩種:synchronized
依賴JVM
實現鎖,該關鍵字作用物件的作用範圍內同一時刻只能有一個執行緒進行操作。另一種LOCK
,是JDK
提供的程式碼層面的鎖,依賴CPU
指令,代表性是ReentrantLock
。
2)可見性:
一個執行緒對主記憶體的修改及時被其他執行緒看到。
JVM
提供了synchronized
和volatile
,volatile
的可見性是通過記憶體屏障和禁止重排序實現的,volatile
會在寫操作時,在寫操作後加一條store
屏障指令,將本地記憶體中的共享變數值重新整理到主記憶體;會在讀操作時,在讀操作前加一條load
指令,從記憶體中讀取共享變數。
3)有序性:
指令沒有被編譯器重排序。
可通過volatile、synchronized、Lock
保證有序性。
10、兩個程序同時要求寫或者讀,能不能實現?如何防止程序的同步?
我認為可以實現,比如兩個程序都讀取日曆程序資料是沒有問題,但同時寫,應該會有衝突。
可以使用共享記憶體實現程序間資料共享。
11、執行緒間操作List
多執行緒數量的問題,一般情況下,多執行緒數量要等於機器CPU
核數-1
.
1.如何讓n個執行緒順序遍歷含有n個元素的List集合
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
public class Test_4 {
/**
* 多執行緒處理list
*
* @param data 資料list
* @param threadNum 執行緒數
*/
public synchronized void handleList(List<String> data, int threadNum) {
int length = data.size();
int tl = length % threadNum == 0 ? length / threadNum : (length
/ threadNum + 1);
for (int i = 0; i < threadNum; i++) {
int end = (i + 1) * tl;
HandleThread thread = new HandleThread("執行緒[" + (i + 1) + "] ", data, i * tl, end > length ? length : end);
thread.start();
}
}
class HandleThread extends Thread {
private String threadName;
private List<String> data;
private int start;
private int end;
public HandleThread(String threadName, List<String> data, int start, int end) {
this.threadName = threadName;
this.data = data;
this.start = start;
this.end = end;
}
public void run() {
List<String> subList = data.subList(start, end)/*.add("^&*")*/;
System.out.println(threadName+"處理了"+subList.size()+"條!");
}
}
public static void main(String[] args) {
Test_4 test = new Test_4();
// 準備資料
List<String> data = new ArrayList<String>();
for (int i = 0; i < 6666; i++) {
data.add("item" + i);
}
test.handleList(data, 5);
System.out.println(ArrayUtils.toString(data));
}
}
2. List多執行緒併發讀取讀取現有的list物件
//測試讀取List的執行緒類,大概34秒
package com.thread.list;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
Map<Long,Integer> map = new HashMap<Long,Integer>();
for(int i = 0;i<1000;i++){
list.add(""+i);
}
int pcount = Runtime.getRuntime().availableProcessors();
long start = System.currentTimeMillis();
for(int i=0;i<pcount;i++){
Thread t = new MyThread1(list,map);
map.put(t.getId(),Integer.valueOf(i));
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println(list.get(i));
}
System.out.println("----"+(System.currentTimeMillis() - start));
}
}
//執行緒類
package com.thread.list;
import java.util.List;
import java.util.Map;
public class MyThread1 extends Thread {
private List<String> list;
private Map<Long,Integer> map;
public MyThread1(List<String> list,Map<Long,Integer> map){
this.list = list;
this.map = map;
}
@Override
public void run() {
int pcount = Runtime.getRuntime().availableProcessors();
int i = map.get(Thread.currentThread().getId());
for(;i<list.size();i+=pcount){
System.out.println(list.get(i));
}
}
}
3.多執行緒分段處理List集合
場景:大資料List
集合,需要對List
集合中的資料同標準庫中資料進行對比,生成新增,更新,取消資料
解決方案:
List
集合分段,
動態建立執行緒池newFixedThreadPool
將對比操作在多執行緒中實現
public static void main(String[] args) throws Exception {
// 開始時間
long start = System.currentTimeMillis();
List<String> list = new ArrayList<String>();
for (int i = 1; i <= 3000; i++) {
list.add(i + "");
}
// 每500條資料開啟一條執行緒
int threadSize = 500;
// 總資料條數
int dataSize = list.size();
// 執行緒數
int threadNum = dataSize / threadSize + 1;
// 定義標記,過濾threadNum為整數
boolean special = dataSize % threadSize == 0;
// 建立一個執行緒池
ExecutorService exec = Executors.newFixedThreadPool(threadNum);
// 定義一個任務集合
List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
Callable<Integer> task = null;
List<String> cutList = null;
// 確定每條執行緒的資料
for (int i = 0; i < threadNum; i++) {
if (i == threadNum - 1) {
if (special) {
break;
}
cutList = list.subList(threadSize * i, dataSize);
} else {
cutList = list.subList(threadSize * i, threadSize * (i + 1));
}
// System.out.println("第" + (i + 1) + "組:" + cutList.toString());
final List<String> listStr = cutList;
task = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + "執行緒:" + listStr);
return 1;
}
};
// 這裡提交的任務容器列表和返回的Future列表存在順序對應的關係
tasks.add(task);
}
List<Future<Integer>> results = exec.invokeAll(tasks);
for (Future<Integer> future : results) {
System.out.println(future.get());
}
// 關閉執行緒池
exec.shutdown();
System.out.println("執行緒任務執行結束");
System.err.println("執行任務消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
}
12、Java中物件的生命週期
1)建立階段(Created):
為物件分配儲存空間,開始構造物件,從超類到子類對static
成員初始化;超類成員變數按順序初始化,遞迴呼叫超類的構造方法,子類成員變數按順序初始化,子類構造方法呼叫。
2)應用階段(In Use):
物件至少被一個強引用持有著。
3)不可見階段(Invisible):
程式執行已超出物件作用域
4)不可達階段(Unreachable):
該物件不再被強引用所持有
5)收集階段(Collected):
假設該物件重寫了finalize()
方法且未執行過,會去執行該方法。
6)終結階段(Finalized):
物件執行完finalize()
方法仍處於不可達狀態,等待垃圾回收器對該物件空間進行回收。
7)物件空間重新分配階段(De-allocated):
垃圾回收器對該物件所佔用的記憶體空間進行回收或再分配,該物件徹底消失。
13、static synchronized 方法的多執行緒訪問和作用
static synchronized
控制的是類的所有例項訪問,不管new
了多少物件,只有一份,所以對該類的所有物件都加了鎖。限制多執行緒中該類的所有例項同時訪問JVM
中該類對應的程式碼。
14、同一個類裡面兩個synchronized方法,兩個執行緒同時訪問的問題
如果synchronized
修飾的是靜態方法,鎖的是當前類的class
物件,進入同步程式碼前要獲得當前類物件的鎖;
普通方法,鎖的是當前例項物件,進入同步程式碼前要獲得的是當前例項的鎖;
同步程式碼塊,鎖的是括號裡面的物件,對給定的物件加鎖,進入同步程式碼塊庫前要獲得給定物件鎖;
如果兩個執行緒訪問同一個物件的synchronized
方法,會出現競爭,如果是不同物件,則不會相互影響。
15、volatile的原理
有volatile
變數修飾的共享變數進行寫操作的時候會多一條彙編程式碼,lock addl $0x0,lock
字首的指令在多核處理器下會將當前處理器快取行的資料會寫回到系統記憶體,這個寫回記憶體的操作會引起在其他CPU
裡快取了該記憶體地址的資料無效。同時lock
字首也相當於一個記憶體屏障,對記憶體操作順序進行了限制。
16、synchronized原理
synchronized
通過物件的物件頭(markword)
來實現鎖機制,java
每個物件都有物件頭,都可以為synchronized
實現提供基礎,都可以作為鎖物件,在位元組碼層面synchronized
塊是通過插入monitorenter monitorexit
完成同步的。持有monitor
物件,通過進入、退出這個Monitor
物件來實現鎖機制。
17、談談NIO的理解
NIO( New Input/ Output)
引入了一種基於通道和緩衝區的I/O
方式,它可以使用 Native
函式庫直接分配堆外記憶體,然後通過一個儲存在Java
堆的 DirectByteBuffer
物件作為這塊記憶體的引用進行操作,避免了在Java
堆和Native
堆中來回複製資料。 NIO
是一種同步非阻塞的 IO
模型。同步是指執行緒不斷輪詢IO
事件是否就緒,非阻塞是指執行緒在等待IO
的時候,可以同時做其他任務。同步的核心就是Selector,Selector
代替了執行緒本身輪詢IO
事件,避免了阻塞同時減少了不必要的執行緒消耗;非阻塞的核心就是通道和緩衝區,當IO
事件就緒時,可以通過寫道緩衝區,保證IO
的成功,而無需執行緒阻塞式地等待。
18.ReentrantLock 、Lock、synchronized和volatile比較
1)volatile:
解決變數在多個執行緒間的可見性,但不能保證原子性,只能用於修飾變數,不會發生阻塞。volatile
能遮蔽編譯指令重排,不會把其後面的指令排到記憶體屏障之前的位置,也不會把前面的指令排到記憶體屏障的後面。多用於平行計算的單例模式。volatile
規定CPU
每次都必須從記憶體讀取資料,不能從CPU
快取中讀取,保證了多執行緒在多CPU
計算中永遠拿到的都是最新的值。
2)synchronized:
互斥鎖,操作互斥,併發執行緒過來,序列獲得鎖,序列執行程式碼。解決的是多個執行緒間訪問共享資源的同步性,可保證原子性,也可間接保證可見性,因為它會將私有記憶體和公有記憶體中的資料做同步。可用來修飾方法、程式碼塊。會出現阻塞。synchronized
發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生。非公平鎖,每次都是相互爭搶資源。
3)lock
是一個介面,而synchronized
是java
中的關鍵字,synchronized
是內建語言的實現。lock
可以讓等待鎖的執行緒響應中斷。在發生異常時,如果沒有主動通過unLock()
去釋放鎖,則可能造成死鎖現象,因此使用Lock
時需要在finally
塊中釋放鎖。
4)ReentrantLock
可重入鎖,鎖的分配機制是基於執行緒的分配,而不是基於方法呼叫的分配。ReentrantLock
有tryLock
方法,如果鎖被其他執行緒持有,返回false
,可避免形成死鎖。對程式碼加鎖的顆粒會更小,更節省資源,提高程式碼效能。ReentrantLock
可實現公平鎖和非公平鎖,公平鎖就是先來的先獲取資源。ReentrantReadWriteLock
用於讀多寫少的場合,且讀不需要互斥場景。
至此,本篇已結束,如有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!
相關推薦
Python多執行緒、多程序和協程的例項講解
執行緒、程序和協程是什麼 執行緒、程序和協程的詳細概念解釋和原理剖析不是本文的重點,本文重點講述在Python中怎樣實際使用這三種東西 參考: 程序、執行緒、協程之概念理解 程序(Process)是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。執
Thread和Runnable的區別和聯絡、多次start一個執行緒會怎麼樣
一、Java有兩種方式實現多執行緒,第一個是繼承Thread類,第二個是實現Runnable介面。他們之間的聯絡: 1、Thread類實現了Runable介面。 2、都需要重寫裡面Run方法。 二、實現Runnable介面相對於繼承Thread類來說,有如下顯著的好處:
Python中單執行緒、多執行緒和多程序的效率對比實驗
Python是執行在直譯器中的語言,查詢資料知道,python中有一個全域性鎖(GIL),在使用多程序(Thread)的情況下,不能發揮多核的優勢。而使用多程序(Multiprocess),則可以發揮多核的優勢真正地提高效率。 對比實驗 資料顯示,如果多執行緒的程序是CPU密集型的,那多執行緒並不能有多少
執行緒、多執行緒和執行緒池面試專題
極力推薦文章:歡迎收藏 Android 乾貨分享 閱讀五分鐘,每日十點,和您一起終身學習,這裡是程式設計師Android 本篇文章主要介紹 Android 開發中的部分知識點,通過閱讀本篇文章,您將收穫以下內容: 1、開啟執行緒的三種方式? 1)繼承Thread類,重寫run()方法,在run()方法
10-多執行緒、多程序和執行緒池程式設計
一、多執行緒、多程序和執行緒池程式設計 1.1、Python中的GIL鎖 CPython中,global interpreter lock(簡稱GIL)是一個互斥體,用於保護對Python物件的訪問,從而防止多個執行緒一次執行Python位元組碼(也就是說,GIL鎖每次只能允許一個執行緒工作,無法多個執行
python多執行緒、多程序、協程的使用
本文主要介紹多執行緒、多程序、協程的最常見使用,每個的詳細說明與介紹有時間會在以後的隨筆中體現。 一、多執行緒 1.python通過兩個標準庫thread和threading提供對執行緒的支援。thread提供了低級別的、原始的執行緒以及一個簡單的鎖。threading通過對thread模組
[進階]-多執行緒、多程序、非同步IO實用例子
在編寫爬蟲時,效能的消耗主要在IO請求中,當單程序單執行緒模式下請求URL時必然會引起等待,從而使得請求整體變慢。以下程式碼預設執行環境為python3。 目錄 一、多執行緒、多程序 1.同步執行 2.多執行緒執行 3.多執行緒+回撥函式執行 4.多程序執行 5.多程
多執行緒、多程序之比較,以及三種執行緒模型。
工作幾年找工作幾乎總會被問,從最開始的從網上看答案,到現在憑自己的經驗去說,這個問題似乎也是經驗積累的一個驗證,最近沒事就總結一下吧: 程序和執行緒的定義、比較等: 程序:處於活動狀態的計算機程式。程序就是在作業系統中 執行特定的任務,程序針對
Python3:談談python的GIL、多執行緒、多程序
本文只是適合初認識多執行緒的小夥伴,裡面的概念和原理一定要搞清楚, 不然以後設計多執行緒,多程序會出很大的錯. GIL的全稱是Global Interpreter Lock(全域性直譯器鎖),來源是python設計之初的考慮,為了資料安全所做的決定。 GIL 的特點: P
Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊
Python 多執行緒、多程序 (一)之 原始碼執行流程、GIL Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊 Python 多執行緒、多程序 (三)之 執行緒程序對比、多執行緒 一、python多執行緒 對於I/O操作的時候,程序與執行緒的效能差別不大,甚至由於執行緒更輕量級,效能更高
Python 多執行緒、多程序 (一)之 原始碼執行流程、GIL
Python 多執行緒、多程序 (一)之 原始碼執行流程、GIL Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊 Python 多執行緒、多程序 (三)之 執行緒程序對比、多執行緒 一、python程式的執行原理 許多時候,在執行一個python檔案的時候,會發現在同一目錄下會出現一個__
Python 多執行緒、多程序 (三)之 執行緒程序對比、多程序
Python 多執行緒、多程序 (一)之 原始碼執行流程、GIL Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊 Python 多執行緒、多程序 (三)之 執行緒程序對比、多執行緒 一、多執行緒與多程序的對比 在之前簡單的提過,CPython中的GIL使得同一時刻只能有一個執行緒執行,即併
CPU如何執行程序、多執行緒,他們之間的關係是怎樣的
好文章分享,轉自:https://www.cnblogs.com/csfeng/p/8670704.html 當面臨這些問題的時候,有兩個關鍵詞無法繞開,那就是並行和併發。 首先,要先了解幾個概念: 1、程序是程式的一次執行。 2、程序是資源分配的基本單位(
Python多程序、多執行緒、多協程的理解
首先我們來了解下python中的程序,執行緒以及協程! 從計算機硬體角度: 計算機的核心是CPU,承擔了所有的計算任務。 一個CPU,在一個時間切片裡只能執行一個程式。 從作業系統的角度: 程序和執行緒,都是一種CPU的執行單元。 程序:表示一個程式的上下文執行活
建立Java多執行緒的兩種方式和執行緒異常
一.使用多執行緒的兩種方法 使用多執行緒的兩種方法有:繼承Thread類和實現runable介面。 二.繼承Thread類 來看一下thread類的原始碼: class Thread implements Runnable { 首先可以看出thread類也是實現Runable介面的run方法如下:
程序、執行緒、多執行緒相關總結
一、說說概念 1、程序(process) 狹義定義:程序就是一段程式的執行過程。 廣義定義:程序是一個具有一定獨立功能的程式關於某個資料集合的一次執行活動。它是作業系統動態執行的基本單元,在傳統的作業系統中,程序既是基本的分配單元,也是基本的執行單元。 簡單的來講程序
認識多工、多程序、單執行緒、多執行緒
要認識多執行緒就要從作業系統的原理說起。 以前古老的DOS作業系統(V 6.22)是單任務的,還沒有執行緒的概念,系統在每次只能做一件事情。比如你在copy東西的時候不能rename檔名。為了提高系統的利用效率,採用批處理來批量執行任務。 現在的作業系統都是多工作業
C# 基礎(十四)C#單例模式:首先介紹 單執行緒、多執行緒、加鎖 單例模式。然後介紹單例模式的執行緒同步:多執行緒有序訪問共享記憶體。
一、簡介 本篇文章將介紹如何使用單例模式,也就是類的例項化,在整個專案的生命週期內,只例項化一次。在單例模式中,往往可以看到如SourceCode.cs:這樣的結構的。 SourceCode.cs: public class Singleton { private static
單執行緒、多執行緒以及執行緒安全個人理解
在這裡,我不對多執行緒原理在做闡述。想了解的讀者可以參考:這裡,我將抽象的概念具體化,通過和尚挑水的故事對多執行緒做解釋。1、首先定義和尚類Monkpackage com.stu.thread; /** * 和尚類 * @author jj * */ public
Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊
一、python多執行緒 對於I/O操作的時候,程序與執行緒的效能差別不大,甚至由於執行緒更輕量級,效能更高。這裡的I/O包括網路I/O和檔案I/O 1、例項 假如利用socket傳送http請求,也就是網路I/O。爬取列表網頁中的寫href連結,然後獲取href連結之後,在爬去連結的網頁詳情。 如果不適用