成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

并發(fā)學(xué)習(xí)筆記(1)

objc94 / 3410人閱讀

摘要:共享數(shù)據(jù)使線程之間的通信比進(jìn)程之間的通信更有效。并發(fā)模型和的區(qū)別說明的作用是啟動(dòng)一個(gè)新線程操作系統(tǒng)級(jí)別,有一個(gè)方法啟動(dòng)新線程,新線程會(huì)執(zhí)行相應(yīng)的方法。多帶帶調(diào)用會(huì)在當(dāng)前線程中執(zhí)行并不會(huì)啟動(dòng)新線程創(chuàng)建一個(gè)線程即可但是這個(gè)線程沒有執(zhí)行任何代碼段。

tutorials site

并發(fā)Concurrency發(fā)展的歷史
     單CPU,一次只能運(yùn)行一個(gè)程序 -- 多任務(wù),一次同時(shí)運(yùn)行多個(gè)任務(wù) (問題是每個(gè)任務(wù)不能永遠(yuǎn)占有資源或者CPU,不再使用資源或者CPU的程序需要釋放掉自己的資源) -- 多線程,每個(gè)任務(wù)都有多線程進(jìn)行處理,每個(gè)執(zhí)行著的線程都可以當(dāng)做是一個(gè)CPU。(問題是 每個(gè)線程都執(zhí)行相同的任務(wù),因此同時(shí)讀和寫同一段內(nèi)存,這會(huì)導(dǎo)致單線程不能出現(xiàn)的問題)
     舉個(gè)例子: 如果一個(gè)線程讀了一塊內(nèi)存 同時(shí)發(fā)生了另一個(gè)線程寫到了這塊內(nèi)存。那么第一個(gè)線程讀到的是什么? old value or the value just wriiten or a value mid between the two. 如果更多的線程同時(shí)寫到了這個(gè)內(nèi)存,第一個(gè)線程讀到什么。
     Therefore it is important as a developer to know how to take the right precautions - meaning learning to control how threads access shared resources like memory, files, databases etc. That is one of the topics this Java concurrency tutorial addresses.

多進(jìn)程和多線程的區(qū)別?
本質(zhì)的區(qū)別在于每個(gè)進(jìn)程擁有自己的一整套變量,而線程則共享數(shù)據(jù)。共享數(shù)據(jù)使線程之間的通信比進(jìn)程之間的通信更有效。

此外在有些操作系統(tǒng)中,與進(jìn)程相比較,線程更加輕量級(jí),創(chuàng)建,撤銷一個(gè)線程比啟動(dòng)線程開銷要小很多。

棧的組成

JVM 的內(nèi)存模型 可以分為調(diào)用棧,堆,方法區(qū),寄存器,本地方法棧;其中主要組成是前二。

同一進(jìn)程中的多條線程將共享該進(jìn)程中的全部系統(tǒng)資源,如虛擬地址空間,文件描述符和信號(hào)處理等等。但同一進(jìn)程中的多個(gè)線程有各自的調(diào)用棧(call stack),自己的寄存器環(huán)境(register context),自己的線程本地存儲(chǔ)(thread-local storage)

每一個(gè)在JVM中運(yùn)行的線程都有自己的調(diào)用棧call stack, 調(diào)用棧存儲(chǔ)著該線程調(diào)用了哪些方法以及這些方法的局部變量。每個(gè)棧只能查看自己的局部變量,無法查看其它棧的局部變量。

  

Objects on the heap can be accessed by all threads that have a reference to the object. When a thread has access to an object, it can also get access to that object"s member variables. If two threads call a method on the same object at the same time, they will both have access to the object"s member variables, but each thread will have its own copy of the local variables.


 advantage and disadvantage

使用并發(fā)的好處:

* 更好的資源利用率
* 更精簡(jiǎn)的程序設(shè)計(jì)(一個(gè)線程負(fù)責(zé)讀,一個(gè)線程負(fù)責(zé)寫,一個(gè)線程只做一個(gè)功能,這樣程序設(shè)計(jì)精簡(jiǎn)多了)
* 更多響應(yīng)的程序 (服務(wù)器監(jiān)聽線程,處理線程的例子)

使用并發(fā)的代價(jià):

* 設(shè)計(jì)更復(fù)雜

Code executed by multiple threads accessing shared data need special attention. Thread interaction is far from always simple. Errors arising from incorrect thread synchronization can be very hard to detect, reproduce and fix.

* 上下文切換

When a CPU switches from executing one thread to executing another, the CPU needs to save the local data, program pointer etc. of the current thread, and load the local data, program pointer etc. of the next thread to execute. This switch is called a "context switch".

* 消耗資源

CPU需要額外的空間時(shí)間去維護(hù)一個(gè)線程。

并發(fā)模型

Creating and Starting java threads

start 和 run的區(qū)別說明

* start() 的作用是 啟動(dòng)一個(gè)新線程(操作系統(tǒng)級(jí)別,有一個(gè)native方法start0() 啟動(dòng)新線程),新線程會(huì)執(zhí)行相應(yīng)的run方法。
* run() 和普通的成員方法一樣,可以被重復(fù)調(diào)用。 多帶帶調(diào)用run() 會(huì)在當(dāng)前線程中執(zhí)行run() 并不會(huì)啟動(dòng)新線程

創(chuàng)建一個(gè)線程Thread thread = new Thread(); thread.start() 即可
但是這個(gè)線程沒有執(zhí)行任何代碼段。

有兩種方式可以指定哪段代碼 一個(gè)線程會(huì)執(zhí)行。

繼承Thread - Thread Subclass

java  public class MyThread extends Thread {

    public void run(){
       System.out.println("MyThread running");
    }
  }

To create and start the above thread you can do like this:

java  MyThread myThread = new MyThread();
  myTread.start();

覆蓋run方法 - Runnable Interface Implemention
第二種方式指定線程應(yīng)該運(yùn)行那端代碼 是創(chuàng)建一個(gè)類執(zhí)行java.lang.Runnable接口

  public class MyRunnable implements Runnable {

    public void run(){
       System.out.println("MyRunnable running");
    }
  }

To have the run() method executed by a thread, pass an instance of MyRunnable to a Thread in its constructor. Here is how that is done:

Thread thread = new Thread(new MyRunnable());
thread.start();
Race Conditions and Critical Sections
  

The problems arise when multiple threads access the same resources.For instance the same memory (variables, arrays, or objects), systems (databases, web services etc.) or files. In fact, problems only arise if one or more of the threads write to these resources. It is safe to let multiple threads read the same resources, as long as the resources do not change.

  

The situation where two threads compete for the same resource, where the sequence in which the resource is accessed is significant, is called race conditions. A code section that leads to race conditions is called a critical section. In the previous example the method add() is a critical section, leading to race conditions. Race conditions can be avoided by proper thread synchronization in critical sections.

Thread Safety and Shared Resources
  

Code that is safe to call by multiple threads simultanously is called thread safe. If a piece of code is thread safe, then it contains no race conditions. Race condition only occur when multiple threads update shared resources. Therefore it is important to know what resources Java threads share when executing.

Java 不共享的資源有:

局部變量 Local varables
局部變量(方法內(nèi)部變量)存儲(chǔ)在每個(gè)線程自己的棧里面,這意味著局部變量不會(huì)被多個(gè)線程共享。這也意味著所有局部變量都是線程安全的thread safe.
比如:

public void someMethod(){
  long threadSafeInt = 0;
  threadSafeInt++;
}

Java 共享的資源有:

局部對(duì)象引用 Local Object References
引用本身是線程安全的,因?yàn)樗木植孔兞?。但是引用?指的對(duì)象object并非存儲(chǔ)在線程的局部棧的,而是存儲(chǔ)在共享堆里 shared heap。 每個(gè)線程在各自的方法內(nèi)創(chuàng)建的局部對(duì)象,只要不作為返回值返回,其他線程訪問不到,不產(chǎn)生競(jìng)爭(zhēng)就不會(huì)有安全問題

比如如下的例子,因?yàn)閘ocalObject沒有作為返回值返回,其他的線程獲取不到這個(gè)對(duì)象的

javapublic void someMethod(){
  LocalObject localObject = new LocalObject();
  localObject.callMethod();
  method2(localObject);
}

public void method2(LocalObject localObject){
  localObject.setValue("value");
}

對(duì)象成員變量
對(duì)象成員與對(duì)象一起存儲(chǔ)在堆里面,對(duì)象成員是屬于類的,局部對(duì)象引用是屬于方法的,不同的線程訪問或者修改一個(gè)類的成員時(shí)就會(huì)存在競(jìng)爭(zhēng).

比如這個(gè)例子中,方法add就是線程不安全的(因?yàn)閎uild是對(duì)象成員變量,多線程都對(duì)它同時(shí)操作)。

public class NotThreadSafe{
  StringBuilder builder = new StringBuilder();
  public add(String text){
    this.builder.append(text);
  }
}

  如果兩個(gè)線程同時(shí)調(diào)用同一個(gè) NotThreadSafe 實(shí)例的 add() 方法就會(huì)引起race condition。比如:

NotThreadSafe sharedInstance = new NotThreadSafe();
new Thread(new MyRunnable(sharedInstance)).start(); // 線程1
new Thread(new MyRunnable(sharedInstance)).start(); // 線程2
public class MyRunnable implements Runnable{
  NotThreadSafe instance = null;
  public MyRunnable(NotThreadSafe instance){
    this.instance = instance;
  }
  public void run(){
    this.instance.add("some text");
  }
}

然而如果兩個(gè)線程在不同的實(shí)例上面同時(shí)調(diào)用 add() 方法并不會(huì)引起靜態(tài)條件。下面是稍微修改之后的例子:

new Thread(new MyRunnable(new NotThreadSafe())).start();
new Thread(new MyRunnable(new NotThreadSafe())).start();

  現(xiàn)在這兩個(gè)線程都有自己的 NotThreadSafe 實(shí)例,所以它們對(duì) add 方法的調(diào)用并不會(huì)妨礙對(duì)方,這段代碼沒有競(jìng)態(tài)條件。所以即使一個(gè)對(duì)象不是線程安全的,仍可以找到一個(gè)方式來消除競(jìng)態(tài)條件?!?br> 可以使用線程逃逸準(zhǔn)則 Thread Control Escape Rule 來判斷是否代碼訪問的資源是線程安全的。

  

如果一個(gè)資源在一個(gè)線程的控制下被創(chuàng)建、使用和銷毀并且永遠(yuǎn)不會(huì)逃脫線程的控制,則該資源的使用是線程安全的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65302.html

相關(guān)文章

  • Java 并發(fā)學(xué)習(xí)筆記(二)

    摘要:請(qǐng)參看前一篇文章并發(fā)學(xué)習(xí)筆記一原子性可見性有序性問題六等待通知機(jī)制什么是等待通知機(jī)制當(dāng)線程不滿足某個(gè)條件,則進(jìn)入等待狀態(tài)如果線程滿足要求的某個(gè)條件后,則通知等待的線程重新執(zhí)行。經(jīng)極客時(shí)間并發(fā)編程實(shí)戰(zhàn)專欄內(nèi)容學(xué)習(xí)整理 請(qǐng)參看前一篇文章:Java 并發(fā)學(xué)習(xí)筆記(一)——原子性、可見性、有序性問題 六、等待—通知機(jī)制 什么是等待通知—機(jī)制?當(dāng)線程不滿足某個(gè)條件,則進(jìn)入等待狀態(tài);如果線程滿足要...

    zgbgx 評(píng)論0 收藏0
  • Java 并發(fā)學(xué)習(xí)筆記(一)——原子性、可見性、有序性問題

    摘要:最后,總結(jié)一下,導(dǎo)致并發(fā)問題的三個(gè)源頭分別是原子性一個(gè)線程在執(zhí)行的過程當(dāng)中不被中斷??梢娦砸粋€(gè)線程修改了共享變量,另一個(gè)線程能夠馬上看到,就叫做可見性。 計(jì)算機(jī)的 CPU、內(nèi)存、I/O 設(shè)備的速度一直存在較大的差異,依次是 CPU > 內(nèi)存 > I/O 設(shè)備,為了權(quán)衡這三者的速度差異,主要提出了三種解決辦法: CPU 增加了緩存,均衡和內(nèi)存的速度差異 發(fā)明了進(jìn)程、線程,分時(shí)復(fù)用 CP...

    Chao 評(píng)論0 收藏0
  • 并發(fā)學(xué)習(xí)筆記 (4)

    摘要:不剝奪條件進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。如果能確保所有的線程都是按照相同的順序獲得鎖,那么死鎖就不會(huì)發(fā)生。按照順序加鎖是一種有效的死鎖預(yù)防機(jī)制。這種機(jī)制存在一個(gè)問題,在中不能對(duì)同步塊設(shè)置超時(shí)時(shí)間。 [tutorial site][1] 死鎖 deadlock 死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因競(jìng)爭(zhēng)資源而造成的一種互相等待的現(xiàn)在,若無外力作用,它們都無法推...

    shiguibiao 評(píng)論0 收藏0
  • 并發(fā)學(xué)習(xí)筆記 (6)

    摘要:每個(gè)通過網(wǎng)絡(luò)到達(dá)服務(wù)器的連接都被包裝成一個(gè)任務(wù)并且傳遞給線程池。線程池的線程會(huì)并發(fā)的處理連接上的請(qǐng)求。用線程池控制線程數(shù)量,其他線程排隊(duì)等候。實(shí)現(xiàn)包,線程池頂級(jí)接口是但是嚴(yán)格意義講并不是一個(gè)線程。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。 tutorial site1tutorial site2 一個(gè)問題: 每啟動(dòng)一個(gè)新線程都會(huì)有相應(yīng)的性能開銷(涉及到OS的交互:創(chuàng)建線程,銷毀線程...

    superw 評(píng)論0 收藏0
  • Go語言核心36講(Go語言實(shí)戰(zhàn)與應(yīng)用十二)--學(xué)習(xí)筆記

    摘要:除此之外,把并發(fā)安全字典封裝在一個(gè)結(jié)構(gòu)體類型中,往往是一個(gè)很好的選擇。請(qǐng)看下面的代碼如上所示,我編寫了一個(gè)名為的結(jié)構(gòu)體類型,它代表了鍵類型為值類型為的并發(fā)安全字典。在這個(gè)結(jié)構(gòu)體類型中,只有一個(gè)類型的字段。34 | 并發(fā)安全字典sync.Map (上)我們今天再來講一個(gè)并發(fā)安全的高級(jí)數(shù)據(jù)結(jié)構(gòu):sync.Map。眾所周知,Go 語言自帶的字典類型map并不是并發(fā)安全的。前導(dǎo)知識(shí):并發(fā)安全字典誕生...

    不知名網(wǎng)友 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<