Java中怎样创建线程安全的方法
面試問(wèn)題:
下面的方法是否線(xiàn)程安全?怎樣讓它成為線(xiàn)程安全的方法?
class MyCounter {private static int counter = 0;public static int getCount() {return counter++;} }本篇文章將解釋一個(gè)常見(jiàn)的面試題,該問(wèn)題被谷歌和很多其它公司問(wèn)起過(guò)。它涉及的相對(duì)比較初級(jí),而不是關(guān)于怎樣去設(shè)計(jì)復(fù)雜的并發(fā)程序。
首先,這個(gè)問(wèn)題的答案是No,因?yàn)閏ounter++操作不是一個(gè)原子操作,而是由多個(gè)原子操作組成。
舉個(gè)例子,在如下情況:一個(gè)線(xiàn)程正在訪(fǎng)問(wèn)該數(shù)據(jù),另一個(gè)線(xiàn)程正在執(zhí)行遞增操作;
當(dāng)線(xiàn)程Thread 1在t1時(shí)刻訪(fǎng)問(wèn)該方法,線(xiàn)程Thread 2有可能還沒(méi)執(zhí)行完這個(gè)方法的操作。因此,返回線(xiàn)程Thread 1的值有可能還沒(méi)被遞增過(guò)。
使getCount方法成為線(xiàn)程安全-方式一
使用關(guān)鍵字synchronized修飾getCount方法可以使它線(xiàn)程安全。當(dāng)使用synchronized修飾靜態(tài)方法,該類(lèi)對(duì)象成為了鎖。
使用synchronized就足夠了嗎,答案是Yes.
class MyCounter {private static int counter = 0;public static synchronized int getCount() {return counter++;} }如果方法不是靜態(tài)方法,那么使用關(guān)鍵字synchronized同步的將是實(shí)例對(duì)象,而不是類(lèi)對(duì)象。
使getCount方法成為線(xiàn)程安全-方式二
在這個(gè)特殊的計(jì)數(shù)例子里,通過(guò)使用java.util.concurrent.atomic包下的AtomicInteger原子類(lèi),可以使count++操作變成原子操作,如下。
import java.util.concurrent.atomic.AtomicInteger; public class MyCounter {private static AtomicInteger counter = new AtomicInteger(0);public static int getCount() {return counter.getAndIncrement();} }其它一些有用的關(guān)于線(xiàn)程安全的事實(shí)
在Java中本地變量是線(xiàn)程安全的。
每一個(gè)線(xiàn)程都會(huì)有一個(gè)自己的棧,兩個(gè)不同的線(xiàn)程是不會(huì)共享同一個(gè)棧的。
所有方法內(nèi)部的本地變量將會(huì)在棧中分配空間,一旦當(dāng)前線(xiàn)程的方法執(zhí)行完畢,棧幀將馬上被移除。
?
譯文鏈接:http://www.programcreek.com/2014/02/how-to-make-a-method-thread-safe-in-java/
?
轉(zhuǎn)載于:https://www.cnblogs.com/chenpi/p/5518264.html
總結(jié)
以上是生活随笔為你收集整理的Java中怎样创建线程安全的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 现代密码学应用的范例-PGP
- 下一篇: java读取InputStream输入流