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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA多线程和并发

發(fā)布時間:2024/4/13 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA多线程和并发 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1. 進(jìn)程和線程之間有什么不同? 一個進(jìn)程是一個獨(dú)立(self contained)的運(yùn)行環(huán)境,它可以被看作一個程序或者一個應(yīng)用。 而線程是在進(jìn)程中執(zhí)行的一個任務(wù)。2. 多線程編程的好處是什么? 多個線程被并發(fā)的執(zhí)行以提高程序的效率,CPU不會因為某個線程需要等待資源而進(jìn)入空閑狀態(tài)。3. 用戶線程和守護(hù)線程有什么區(qū)別? 當(dāng)我們在Java程序中創(chuàng)建一個線程,它就被稱為用戶線程。 當(dāng)沒有用戶線程在運(yùn)行的時候,JVM關(guān)閉程序并且退出。一個守護(hù)線程創(chuàng)建的子線程依然是守護(hù)線程。4. 我們?nèi)绾蝿?chuàng)建一個線程? 有兩種創(chuàng)建線程的方法:一是實現(xiàn)Runnable接口,然后將它傳遞給Thread的構(gòu)造函數(shù),創(chuàng)建一個Thread對象; 二是直接繼承Thread類。5. 有哪些不同的線程生命周期? 當(dāng)我們在Java程序中新建一個線程時,它的狀態(tài)是New。當(dāng)我們調(diào)用線程的start()方法時,狀態(tài)被改變 為Runnable。線程調(diào)度器會為Runnable線程池中的線程分配CPU時間并且講它們的狀態(tài)改變?yōu)镽unning。 其他的線程狀態(tài)還有Waiting,Blocked 和Dead。6. 可以直接調(diào)用Thread類的run()方法么? 當(dāng)然可以,但是如果我們調(diào)用了Thread的run()方法,它的行為就會和普通的方法一樣,為了在新的線程中執(zhí)行 我們的代碼,必須使用Thread.start()方法。7. 如何讓正在運(yùn)行的線程暫停一段時間? 我們可以使用Thread類的Sleep()方法讓線程暫停一段時間。 需要注意的是,這并不會讓線程終止,一旦從休眠中喚醒線程,線程的狀態(tài)將會被改變?yōu)镽unnable, 并且根據(jù)線程調(diào)度,它將得到執(zhí)行。8. 你對線程優(yōu)先級的理解是什么? 每一個線程都是有優(yōu)先級的,一般來說,高優(yōu)先級的線程在運(yùn)行時會具有優(yōu)先權(quán),但這依賴于線程調(diào)度的實現(xiàn) 線程優(yōu)先級是一個int變量(從1-10),1代表最低優(yōu)先級,10代表最高優(yōu)先級。9. 什么是線程調(diào)度器(Thread Scheduler)和時間分片(Time Slicing)? 線程調(diào)度器是一個操作系統(tǒng)服務(wù),它負(fù)責(zé)為Runnable狀態(tài)的線程分配CPU時間。 時間分片是指將可用的CPU時間分配給可用的Runnable線程的過程。分配CPU時間可以基于線程優(yōu)先級 或者線程等待的時間。10. 在多線程中,什么是上下文切換(context-switching)? 上下文切換是存儲和恢復(fù)CPU狀態(tài)的過程,它使得線程執(zhí)行能夠從中斷點恢復(fù)執(zhí)行。11. 你如何確保main()方法所在的線程是Java程序最后結(jié)束的線程? 我們可以使用Thread類的joint()方法來確保所有程序創(chuàng)建的線程在main()方法退出前結(jié)束。12.線程之間是如何通信的? 當(dāng)線程間是可以共享資源時,線程間通信是協(xié)調(diào)它們的重要的手段。 Object類中wait()\notify()\notifyAll()方法可以用于線程間通信關(guān)于資源的鎖的狀態(tài)。13.為什么線程通信的方法wait(), notify()和notifyAll()被定義在Object類里? 在Java的線程中并沒有可供任何對象使用的鎖和同步器。這就是為什么這些方法是Object類的一部分, 這樣Java的每一個類都有用于線程間通信的基本方法14. 為什么wait(), notify()和notifyAll()必須在同步方法或者同步塊中被調(diào)用? 由于所有的這些方法都需要線程持有對象的鎖,這樣就只能通過同步來實現(xiàn),所以他們只能在同步方法 或者同步塊中被調(diào)用。15. 為什么Thread類的sleep()和yield()方法是靜態(tài)的? Thread類的sleep()和yield()方法將在當(dāng)前正在執(zhí)行的線程上運(yùn)行。所以在其他處于等待狀態(tài)的線程上調(diào)用 這些方法是沒有意義的。16.如何確保線程安全? 在Java中可以有很多方法來保證線程安全——同步17. volatile關(guān)鍵字在Java中有什么作用? 當(dāng)我們使用volatile關(guān)鍵字去修飾變量的時候,所以線程都會直接讀取該變量并且不緩存它。 這就確保了線程讀取到的變量是同內(nèi)存中是一致的。18. 同步方法和同步塊,哪個是更好的選擇? 同步塊是更好的選擇,因為它不會鎖住整個對象(當(dāng)然你也可以讓它鎖住整個對象)。同步方法會鎖住整個 對象,哪怕這個類中有多個不相關(guān)聯(lián)的同步塊,這通常會導(dǎo)致他們停止執(zhí)行并需要等待獲得這個對象上的鎖。19.如何創(chuàng)建守護(hù)線程? 使用Thread類的setDaemon(true)方法可以將線程設(shè)置為守護(hù)線程,需要注意的是,需要在 調(diào)用start()方法前調(diào)用這個方法,否則會拋出IllegalThreadStateException異常。20. 什么是ThreadLocal? ThreadLocal用于創(chuàng)建線程的本地變量,我們知道一個對象的所有線程會共享它的全局變量,所以這些變量 不是線程安全的,我們可以使用同步技術(shù)。但是當(dāng)我們不想使用同步的時候,我們可以選擇ThreadLocal變量。 每個線程都會擁有他們自己的Thread變量,它們可以使用get()\set()方法去獲取他們的默認(rèn)值或者在線程 內(nèi)部改變他們的值。ThreadLocal實例通常是希望它們同線程狀態(tài)關(guān)聯(lián)起來是private static屬性。21. 什么是Thread Group?為什么不建議使用它? ThreadGroup是一個類,它的目的是提供關(guān)于線程組的信息。 ThreadGroup API比較薄弱,它并沒有比Thread提供了更多的功能。它有兩個主要的功能: 一是獲取線程組中處于活躍狀態(tài)線程的列表;二是設(shè)置為線程設(shè)置未捕獲異常處理器 (ncaught exception handler)。22. 什么是死鎖(Deadlock)?如何分析和避免死鎖? 死鎖是指兩個以上的線程永遠(yuǎn)阻塞的情況,這種情況產(chǎn)生至少需要兩個以上的線程和兩個以上的資源。23. 什么是Java Timer類?如何創(chuàng)建一個有特定時間間隔的任務(wù)? java.util.Timer是一個工具類,可以用于安排一個線程在未來的某個特定時間執(zhí)行。Timer類可以 用安排一次性任務(wù)或者周期任務(wù)。 java.util.TimerTask是一個實現(xiàn)了Runnable接口的抽象類,我們需要去繼承這個類來創(chuàng)建我們自己的 定時任務(wù)并使用Timer去安排它的執(zhí)行。25. 什么是線程池?如何創(chuàng)建一個Java線程池? 一個線程池管理了一組工作線程,同時它還包括了一個用于放置等待執(zhí)行的任務(wù)的隊列。java.util.concurrent.Executors提供了一個 java.util.concurrent.Executor接口的實現(xiàn)用于 創(chuàng)建線程池。1. 什么是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)? 原子操作是指一個不受其他操作影響的操作任務(wù)單元。原子操作是在多線程環(huán)境下避免數(shù)據(jù)不一致必須的手段。 int++并不是一個原子操作,所以當(dāng)一個線程讀取它的值并加1時,另外一個線程有可能會讀到之前的值, 這就會引發(fā)錯誤。 為了解決這個問題,必須保證增加操作是原子的,在JDK1.5之前我們可以使用同步技術(shù)來做到這一點。2. Java Concurrency API中的Lock接口(Lock interface)是什么?對比同步它有什么優(yōu)勢? Lock接口比同步方法和同步塊提供了更具擴(kuò)展性的鎖操作。他們允許更靈活的結(jié)構(gòu),可以具有 完全不同的性質(zhì),并且可以支持多個相關(guān)類的條件對象。3. 什么是Executors框架? Executor框架同java.util.concurrent.Executor 接口在Java 5中被引入。Executor框架是一個根據(jù) 一組執(zhí)行策略調(diào)用,調(diào)度,執(zhí)行和控制的異步任務(wù)的框架。無限制的創(chuàng)建線程會引起應(yīng)用程序內(nèi)存溢出。所以創(chuàng)建一個線程池是個更好的的解決方案,因為可以限制 線程的數(shù)量并且可以回收再利用這些線程。4. 什么是阻塞隊列?如何使用阻塞隊列來實現(xiàn)生產(chǎn)者-消費(fèi)者模型? java.util.concurrent.BlockingQueue的特性是:當(dāng)隊列是空的時,從隊列中獲取或刪除元素的操作將會 被阻塞,或者當(dāng)隊列是滿時,往隊列里添加元素的操作會被阻塞。BlockingQueue 接口是java collections框架的一部分,它主要用于實現(xiàn)生產(chǎn)者-消費(fèi)者問題。5. 什么是Callable和Future? Java 5在concurrency包中引入了java.util.concurrent.Callable 接口,它和Runnable接口很相似, 但它可以返回一個對象或者拋出一個異常。Future提供了get()方法讓我們可以等待Callable結(jié)束并獲取它的執(zhí)行結(jié)果。

關(guān)于synchronized關(guān)鍵字的認(rèn)識

1、Java線程生命周期 Java線程生命周期從大的方面劃分,可以分為四個狀態(tài),即新建、就緒、阻塞和死亡。新建(new):分配了必須的系統(tǒng)資源,并執(zhí)行了初始化。 新建狀態(tài)下的線程表示可以獲得CPU時間片,調(diào)度器可以將其轉(zhuǎn)化為runnable或者blocked狀態(tài)。就緒(runnable): 就緒狀態(tài)表示線程處于隨時可運(yùn)行的狀態(tài),也包括了正在運(yùn)行的狀態(tài) 當(dāng)線程在就緒狀態(tài)時,只要調(diào)度器把時間片分配給線程,線程就能運(yùn)行。阻塞(blocked):當(dāng)線程處于阻塞狀態(tài)時,調(diào)度器將會忽略線程,不會分配給線程任何CPU 時間 也就是說阻塞和就緒兩狀態(tài)區(qū)別在于,調(diào)度器可以給就緒狀態(tài)線程分配CPU時間片, 而無法給阻塞狀態(tài)線程分配CPU時間片,只有當(dāng)線程變成了runnable狀態(tài),它才有可能被執(zhí)行。結(jié)束(terminated):處于結(jié)束狀態(tài)的線程是不可調(diào)度的,并且再也不會得到CPU時間片 這個結(jié)束狀態(tài)比較好理解,不過需要提的是一般而言,線程是在run方法運(yùn)行完成后, 就進(jìn)入了結(jié)束狀態(tài)。這四個狀態(tài)新建(new)和結(jié)束(terminated)沒啥好說的,平時在線程運(yùn)行過程中,我們一般關(guān)注的都是 就緒(runnable)以及阻塞(blocked)兩個狀態(tài),而且這兩個狀態(tài)在一定條件下可以發(fā)生轉(zhuǎn)化2、wait 和 notify 控制線程的就緒(runnable)和阻塞(blockded)兩狀態(tài)的方式之一。 Java的所有對象就繼承自O(shè)bject類,該類中定義了wait和notify方法,而且都是final的native方法3、synchronized關(guān)鍵字使用 終于講到synchronized關(guān)鍵字了,synchronized關(guān)鍵字有三種使用方式 修飾實例方法:作用于當(dāng)前實例加鎖,進(jìn)入同步方法代碼前要獲得當(dāng)前實例的鎖 修飾靜態(tài)方法:作用于當(dāng)前類對象加鎖,進(jìn)入同步方法代碼前要獲得當(dāng)前類對象的鎖 修飾代碼塊:指定加鎖對象,對給定對象加鎖,進(jìn)入同步代碼塊前要獲得給定對象的鎖4、說說wait和sleep wait和sleep都可以使得當(dāng)前線程處于阻塞狀態(tài),失去CPU時間但是相似之外最大的還是區(qū)別 1、wait是針對線程鎖而言的,wait使得當(dāng)前線程失去線程鎖并且沒有被notify時,將沒有機(jī)會再獲取 線程鎖,而sleep沒有線程鎖的概念,只是單純的讓線程失去CPU時間,一旦sleep時間已過,線程便處于 就緒(runnable)狀態(tài),隨時可以獲取CPU時間。 2、wait是Object實例方法,而sleep是Thread的靜態(tài)方法;

java中synchronized關(guān)鍵字的用法

在java編程中,經(jīng)常需要用到同步,而用得最多的也許是synchronized關(guān)鍵字了,下面看看這個關(guān)鍵字的用法。java的內(nèi)置鎖:每個java對象都可以用做一個實現(xiàn)同步的鎖,這些鎖成為內(nèi)置鎖。線程進(jìn)入同步代碼塊 或方法的時候會自動獲得該鎖,在退出同步代碼塊或方法時會釋放該鎖。獲得內(nèi)置鎖的唯一途徑就是進(jìn)入 這個鎖的保護(hù)的同步代碼塊或方法。java內(nèi)置鎖是一個互斥鎖,這就是意味著最多只有一個線程能夠獲得該鎖,當(dāng)線程A嘗試去獲得線程B持有的內(nèi) 置鎖時,線程A必須等待或者阻塞,知道線程B釋放這個鎖,如果B線程不釋放這個鎖,那么A線程將永遠(yuǎn)等待下去。java的對象鎖和類鎖:java的對象鎖和類鎖在鎖的概念上基本上和內(nèi)置鎖是一致的,但是,兩個鎖實際是 有很大的區(qū)別的,對象鎖是用于對象實例方法,或者一個對象實例上的,類鎖是用于類的靜態(tài)方法或者一個類 的class對象上的。我們知道,類的對象實例可以有很多個,但是每個類只有一個class對象,所以不同對象 實例的對象鎖是互不干擾的,但是每個類只有一個類鎖。但是有一點必須注意的是,其實類鎖只是一個概念上的 東西,并不是真實存在的,它只是用來幫助我們理解鎖定實例方法和靜態(tài)方法的區(qū)別的synchronized的用法:synchronized修飾方法和synchronized修飾代碼塊。public class TestSynchronized { public void test1() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public synchronized void test2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { final TestSynchronized myt2 = new TestSynchronized(); Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" ); Thread test2 = new Thread( new Runnable() { public void run() { myt2.test2(); } }, "test2" ); test1.start();; test2.start(); // TestRunnable tr=new TestRunnable(); // Thread test3=new Thread(tr); // test3.start();} }test2 : 4 test2 : 3 test2 : 2 test2 : 1 test2 : 0 test1 : 4 test1 : 3 test1 : 2 test1 : 1 test1 : 0因為第一個同步代碼塊傳入的this,所以兩個同步代碼所需要獲得的對象鎖都是同一個對象鎖, 下面main方法時分別開啟兩個線程,分別調(diào)用test1和test2方法,那么兩個線程都需要獲得該對象鎖, 另一個線程必須等待。運(yùn)行的結(jié)果可以看到:直到test2線程執(zhí)行完畢,釋放掉鎖,test1線程才開始執(zhí)行。可能這個結(jié)果有人會有疑問,代碼里面明明是先開啟test1線程,為什么先執(zhí)行的是test2呢?這是因為java 編譯器在編譯成字節(jié)碼的時候,會對代碼進(jìn)行一個重排序,也就是說,編譯器會根據(jù)實際情況對代碼進(jìn)行一個 合理的排序,編譯前代碼寫在前面,在編譯后的字節(jié)碼不一定排在前面,所以這種運(yùn)行結(jié)果是正常的, 這里是題外話,最主要是檢驗synchronized的用法的正確性如果我們把test2方法的synchronized關(guān)鍵字去掉,執(zhí)行結(jié)果會如何呢?test1 : 4 test2 : 4 test2 : 3 test1 : 3 test1 : 2 test2 : 2 test2 : 1 test1 : 1 test2 : 0 test1 : 01.我們可以看到,結(jié)果輸出是交替著進(jìn)行輸出的,這是因為,某個線程得到了對象鎖,但是另一個線程還是 可以訪問沒有進(jìn)行同步的方法或者代碼。 2.進(jìn)行了同步的方法(加鎖方法)和沒有進(jìn)行同步的方法(普通方法)是互不影響的,一個線程進(jìn)入了 同步方法,得到了對象鎖,其他線程還是可以訪問那些沒有同步的方法(普通方法)。 3.當(dāng)獲取到與對象關(guān)聯(lián)的內(nèi)置鎖時,并不能阻止其他線程訪問該對象,當(dāng)某個線程獲得對象的鎖之后, 只能阻止其他線程獲得同一個鎖。 4.之所以每個對象都有一個內(nèi)置鎖,是為了免去顯式地創(chuàng)建鎖對象。所以synchronized只是一個內(nèi)置鎖的加鎖機(jī)制,當(dāng)某個方法加上synchronized關(guān)鍵字后,就表明要獲得 該內(nèi)置鎖才能執(zhí)行,并不能阻止其他線程訪問不需要獲得該內(nèi)置鎖的方法。類鎖的修飾(靜態(tài))方法和代碼塊:public class TestSynchronized { public void test1() { synchronized(TestSynchronized.class) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public static synchronized void test2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { final TestSynchronized myt2 = new TestSynchronized(); Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" ); Thread test2 = new Thread( new Runnable() { public void run() { TestSynchronized.test2(); } } , "test2" ); test1.start(); test2.start(); // TestRunnable tr=new TestRunnable(); // Thread test3=new Thread(tr); // test3.start();} }test1 : 4 test1 : 3 test1 : 2 test1 : 1 test1 : 0 test2 : 4 test2 : 3 test2 : 2 test2 : 1 test2 : 0其實,類鎖修飾方法和代碼塊的效果和對象鎖是一樣的,因為類鎖只是一個抽象出來的概念,只是為了區(qū)別 靜態(tài)方法的特點,因為靜態(tài)方法是所有對象實例共用的,所以對應(yīng)著synchronized修飾的靜態(tài)方法的鎖也是 唯一的,所以抽象出來個類鎖。下面這塊代碼,synchronized同時修飾靜態(tài)和非靜態(tài)方法 public class TestSynchronized { public synchronized void test1() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static synchronized void test2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { final TestSynchronized myt2 = new TestSynchronized(); Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" ); Thread test2 = new Thread( new Runnable() { public void run() { TestSynchronized.test2(); } }, "test2" ); test1.start(); test2.start(); // TestRunnable tr=new TestRunnable(); // Thread test3=new Thread(tr); // test3.start();} }test1 : 4 test2 : 4 test1 : 3 test2 : 3 test2 : 2 test1 : 2 test2 : 1 test1 : 1 test1 : 0 test2 : 0上面代碼synchronized同時修飾靜態(tài)方法和實例方法,但是運(yùn)行結(jié)果是交替進(jìn)行的,這證明了類鎖和對象鎖 是兩個不一樣的鎖,控制著不同的區(qū)域,它們是互不干擾的。 同樣,線程獲得對象鎖的同時,也可以獲得該類鎖,即同時獲得兩個鎖,這是允許的。synchronized的缺陷:當(dāng)某個線程進(jìn)入同步方法獲得對象鎖,那么其他線程訪問這里對象的同步方法時, 必須等待或者阻塞,這對高并發(fā)的系統(tǒng)是致命的,這很容易導(dǎo)致系統(tǒng)的崩潰。 如果某個線程在同步方法里面發(fā)生了死循環(huán),那么它就永遠(yuǎn)不會釋放這個對象鎖,那么其他線程就要 永遠(yuǎn)的等待。這是一個致命的問題。這個類里面聲明了一個對象實例,SynObject so=new SynObject();在某個方法里面調(diào)用了這個實例的 方法so.testsy();但是調(diào)用這個方法需要進(jìn)行同步,不能同時有多個線程同時執(zhí)行調(diào)用這個方法。這時如果直接用synchronized修飾調(diào)用了so.testsy();代碼的方法,那么當(dāng)某個線程進(jìn)入了這個方法 之后,這個對象其他同步方法都不能給其他線程訪問了。假如這個方法需要執(zhí)行的時間很長,那么其他線程 會一直阻塞,影響到系統(tǒng)的性能。如果這時用synchronized來修飾代碼塊:synchronized(so){so.testsy();},那么這個方法加鎖的對象 是so這個對象,跟執(zhí)行這行代碼的對象沒有關(guān)系,當(dāng)一個線程執(zhí)行這個方法時,這對其他同步方法時 沒有影響的,因為他們持有的鎖都完全不一樣。一個類的對象鎖和另一個類的對象鎖是沒有關(guān)聯(lián)的,當(dāng)一個線程獲得A類的對象鎖時,它同時也可以獲得 B類的對象鎖。打個比方:一個object就像一個大房子,大門永遠(yuǎn)打開。房子里有 很多房間(也就是方法)。這些房間有上鎖的(synchronized方法), 和不上鎖之分(普通方法)。普通情況下鑰匙的使用原則是:“隨用隨借,用完即還。”這時其他人可以不受限制的使用那些不上鎖的房間,一個人用一間可以,兩個人用一間也可以,沒限制。 但是如果當(dāng)某個人想要進(jìn)入上鎖的房間,他就要跑到大門口去看看了。有鑰匙當(dāng)然拿了就走,沒有的話, 就只能等了。要是很多人在等這把鑰匙,等鑰匙還回來以后,誰會優(yōu)先得到鑰匙?Not guaranteed。象前面例子里那個想 連續(xù)使用兩個上鎖房間的家伙,他中間還鑰匙的時候如果還有其他人在等鑰匙,那么沒有任何保證這家伙能 再次拿到。 (JAVA規(guī)范在很多地方都明確說明不保證,像Thread.sleep()休息后多久會返回運(yùn)行,相同 優(yōu)先權(quán)的線程那個首先被執(zhí)行,當(dāng)要訪問對象的鎖被 釋放后處于等待池的多個線程哪個會優(yōu)先得到,等等。 我想最終的決定權(quán)是在JVM,之所以不保證,就是因為JVM在做出上述決定的時候,絕不是簡簡單單根據(jù) 一個 條件來做出判斷,而是根據(jù)很多條。而由于判斷條件太多,如果說出來可能會影響JAVA的推廣,也可能是 因為知識產(chǎn)權(quán)保護(hù)的原因吧。SUN給了個不保證 就混過去了。無可厚非。但我相信這些不確定,并非完全 不確定。因為計算機(jī)這東西本身就是按指令運(yùn)行的。即使看起來很隨機(jī)的現(xiàn)象,其實都是有規(guī)律可尋。學(xué)過 計算機(jī)的都知道,計算機(jī)里隨機(jī)數(shù)的學(xué)名是偽隨機(jī)數(shù),是人運(yùn)用一定的方法寫出來的,看上去隨機(jī)罷了。 另外,或許是因為要想弄的確太費(fèi)事,也沒多大意義,所 以不確定就不確定了吧。看看同步代碼塊。和同步方法有小小的不同。1.從尺寸上講,同步代碼塊比同步方法小。你可以把同步代碼塊看成是沒上鎖房間里的一塊用帶鎖的屏風(fēng) 隔開的空間。2.同步代碼塊還可以人為的指定獲得某個其它對象的key。就像是指定用哪一把鑰匙才能開這個屏風(fēng)的鎖, 你可以用本房的鑰匙;你也可以指定用另一個房子的鑰匙才能開,這樣的話,你要跑到另一棟房子那兒把 那個鑰匙拿來,并用那個房子的鑰匙來打開這個房子的帶鎖的屏風(fēng)。為什么要使用同步代碼塊呢? 首先對程序來講同步的部分很影響運(yùn)行效率,而一個方法通常是先創(chuàng)建一些局部變量,再對這些變量做一些 操作,如運(yùn)算,顯示等等;而同步所覆蓋的代碼越多,對效率的影響就越嚴(yán)重。因此我們通常盡量縮小其影響 范圍如何做?同步代碼塊。我們只把一個方法中該同 步的地方同步,比如運(yùn)算。另外,同步代碼塊可以指定鑰匙 這一特點有個額外的好處,是可以在一定時期內(nèi)霸占某個對象的key。還記得前面說過普通情況下鑰匙的使用 原則嗎。現(xiàn)在不是普通情況了。你所取得的那把鑰匙不是永遠(yuǎn)不還,而是在退出同步代碼塊時才還。

?

總結(jié)

以上是生活随笔為你收集整理的JAVA多线程和并发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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