成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

線程安全問題java代碼 線程安全問題java代碼是什么

Java開發(fā)中線程的安全問題以及產(chǎn)生的原因?

Java如何保證原子性常用的保證Java操作原子性的工具是鎖和同步方法(或者同步代碼塊)。使用鎖,可以保證同一時間只有一個線程能拿到鎖,也就保證了同一時間只有一個線程能執(zhí)行申請鎖和釋放鎖之間的代碼。

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、容縣網(wǎng)絡(luò)推廣、小程序設(shè)計、容縣網(wǎng)絡(luò)營銷、容縣企業(yè)策劃、容縣品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供容縣建站搭建服務(wù),24小時服務(wù)熱線:18982081108,官方網(wǎng)址:jinyejixie.com

與鎖類似的是同步方法或者同步代碼塊。使用非靜態(tài)同步方法時,鎖住的是當(dāng)前實例;使用靜態(tài)同步方法時,鎖住的是該類的Class對象;使用靜態(tài)代碼塊時,鎖住的是synchronized關(guān)鍵字后面括號內(nèi)的對象。

java 程序中怎么保證多線程的運行安全?

并發(fā)編程三要素(線程的安全性問題體現(xiàn)在):

原子性:原子,即一個不可再被分割的顆粒。原子性指的是一個或多個操作要么 全部執(zhí)行成功要么全部執(zhí)行失敗。

可見性:一個線程對共享變量的修改,另一個線程能夠立刻看到。 (synchronized,volatile)

有序性:程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。(處理器可能會對指令進行 重排序)

出現(xiàn)線程安全問題的原因:

線程切換帶來的原子性問題

緩存導(dǎo)致的可見性問題

編譯優(yōu)化帶來的有序性問題

解決辦法:

JDK Atomic開頭的原子類、synchronized、LOCK,可以解決原子性問題

synchronized、volatile、LOCK,可以解決可見性問題

Happens-Before 規(guī)則可以解決有序性問題

Java的List如何實現(xiàn)線程安全?

Java的List如何實現(xiàn)線程安全?

Collections.synchronizedList(names);效率最高,線程安全

Java的List是我們平時很常用的集合,線程安全對于高并發(fā)的場景也十分的重要,那么List如何才能實現(xiàn)線程安全呢 ?

加鎖

首先大家會想到用Vector,這里我們就不討論了,首先討論的是加鎖,例如下面的代碼

public class Synchronized{

private ListString ?names = new LinkedList();

public synchronized void addName(String name ){

names.add("abc");

}

public String getName(Integer index){

Lock lock =new ReentrantLock();

lock.lock();

try {

return names.get(index);

}catch (Exception e){

e.printStackTrace();

}

finally {

lock.unlock();

}

return null;

}

}

synchronized一加,或者使用lock 可以實現(xiàn)線程安全,但是這樣的List要是很多個,代碼量會大大增加。

java自帶類

在java中我找到自帶有兩種方法

CopyOnWriteArrayList

CopyOnWrite 寫入時復(fù)制,它使一個List同步的替代品,通常情況下提供了更好的并發(fā)性,并且避免了再迭代時候?qū)θ萜鞯募渔i和復(fù)制。通常更適合用于迭代,在多插入的情況下由于多次的復(fù)制性能會一定的下降。

下面是add方法的源代碼

public boolean add(E e) {

final ReentrantLock lock = this.lock; // 加鎖 只允許獲得鎖的線程訪問

lock.lock();

try {

Object[] elements = getArray();

int len = elements.length;

// 創(chuàng)建個長度加1的數(shù)組并復(fù)制過去

Object[] newElements = Arrays.copyOf(elements, len + 1);

newElements[len] = e; // 賦值

setArray(newElements); // 設(shè)置內(nèi)部的數(shù)組

return true;

} finally {

lock.unlock();

}

}

Collections.synchronizedList

Collections中有許多這個系列的方法例如

主要是利用了裝飾者模式對傳入的集合進行調(diào)用 Collotions中有內(nèi)部類SynchronizedList

static class SynchronizedListE

extends SynchronizedCollectionE

implements ListE {

private static final long serialVersionUID = -7754090372962971524L;

final ListE list;

SynchronizedList(ListE list) {

super(list);

this.list = list;

}

public E get(int index) {

synchronized (mutex) {return list.get(index);}

}

public E set(int index, E element) {

synchronized (mutex) {return list.set(index, element);}

}

public void add(int index, E element) {

synchronized (mutex) {list.add(index, element);}

}

public E remove(int index) {

synchronized (mutex) {return list.remove(index);}

}

static class SynchronizedCollectionE implements CollectionE, Serializable {

private static final long serialVersionUID = 3053995032091335093L;

final CollectionE c; ?// Backing Collection

final Object mutex; ? ? // Object on which to synchronize

這里上面的mutex就是鎖的對象 在構(gòu)建時候可以指定鎖的對象 主要使用synchronize關(guān)鍵字實現(xiàn)線程安全

/**

* @serial include

*/

static class SynchronizedListE

extends SynchronizedCollectionE

implements ListE {

private static final long serialVersionUID = -7754090372962971524L;

final ListE list;

SynchronizedList(ListE list) {

super(list);

this.list = list;

}

SynchronizedList(ListE list, Object mutex) {

super(list, mutex);

this.list = list;

}

這里只是列舉SynchronizedList ,其他類類似,可以看下源碼了解下。

測試

public class Main {

public static void main(String[] args) {

ListString names = new LinkedList();

names.add("sub");

names.add("jobs");

// 同步方法1 內(nèi)部使用lock

long a = System.currentTimeMillis();

ListString strings = new CopyOnWriteArrayList(names);

for (int i = 0; i 100000; i++) {

strings.add("param1");

}

long b = System.currentTimeMillis();

// 同步方法2 裝飾器模式使用 synchronized

ListString synchronizedList = Collections.synchronizedList(names);

for (int i = 0; i 100000; i++) {

synchronizedList.add("param2");

}

long c = System.currentTimeMillis();

System.out.println("CopyOnWriteArrayList time == "+(b-a));

System.out.println("Collections.synchronizedList time == "+(c-b));

}

}

兩者內(nèi)部使用的方法都不一樣,CopyOnWriteArrayList內(nèi)部是使用lock進行加鎖解鎖完成單線程訪問,synchronizedList使用的是synchronize

進行了100000次添加后時間對比如下:

可以看出來還是使用了synchronize的集合工具類在添加方面更加快一些,其他方法這里篇幅關(guān)系就不測試了,大家有興趣去試一下。

北大青鳥java培訓(xùn):關(guān)于線程安全問題分析?

在學(xué)習(xí)java編程開發(fā)語言的過程中,我們掌握了線程與線程池等相關(guān)技術(shù)知識。

今天,北大青鳥遼寧計算機學(xué)院就關(guān)于線程安全問題給大家做一個簡單的說明和介紹,一起來了解一下吧。

線程安全就是多線程訪問時,采用了加鎖機制,當(dāng)一個線程訪問該類的某個數(shù)據(jù)時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。

不會出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。

線程不安全就是不提供數(shù)據(jù)訪問保護,有可能出現(xiàn)多個線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)。

什么時候考慮到線程安全:一個對象是否需要線程安全,取決于該對象是否被多線程訪問。

這指的是程序中訪問對象的方式,而不是對象要實現(xiàn)的功能。

要使得對象是線程安全的,要采用同步機制來協(xié)同對對象可變狀態(tài)的訪問。

Java常用的同步機制是Synchronized,還包括volatile類型的變量,顯示鎖以及原子變量。

在多個線程中,當(dāng)它們同時訪問同個類時,每次執(zhí)行的結(jié)果和單線程結(jié)果一致,且變量值跟預(yù)期一致,這個類則是線程安全的。

鎖的特性鎖機制的兩種特性:互斥性:即同一時間只允許一個線程持有某個對象的鎖,通過這種特性來實現(xiàn)多線程中的協(xié)調(diào)機制,這樣在同一時間只有一個線程對需同步的代碼塊(復(fù)合操作)進行訪問。

互斥性我們也往往稱為操作的原子性。

可見性:必須確保在鎖被釋放之前,對共享變量所做的修改,對于隨后獲得該鎖的另一個線程是可見的,否則另一個線程可能是在本地緩存的某個副本上繼續(xù)操作從而引起不一致。

掛起、休眠、阻塞和非阻塞掛起:當(dāng)線程被掛起時,其會失去CPU的使用時間,直到被其他線程(用戶線程或調(diào)試線程)喚醒。

休眠:同樣是會失去CPU的使用時間,但是在過了指定的休眠時間之后,它會自動激活,無需喚醒(整個喚醒表面看是自動的,但實際上也得有守護線程去喚醒,只是不需編程者手動干預(yù))。

阻塞:在線程執(zhí)行時,所需要的資源不能得到,則線程被掛起,直到滿足可操作的條件。

非阻塞:在線程執(zhí)行時,所需要的資源不能得到,則線程不是被掛起等待,而是繼續(xù)執(zhí)行其余事情,等待條件滿足了后,收到了通知(同樣是守護線程去做)再執(zhí)行。

Java Swing開發(fā)中的線程安全

SwingAPI的設(shè)計目標(biāo)是強大 靈活和易用 非凡地 我們希望能讓程序員們方便地建立新的Swing組件 不論是從頭開始還是通過擴展我們所提供的一些組件 出于這個目的 我們不要求Swing組件支持多線程訪問 相反 我們向組件發(fā)送請求并在單一線程中執(zhí)行請求 本文討論線程和Swing組件 目的不僅是為了幫助你以線程安全的方式使用SwingAPI 而且解釋了我們?yōu)槭裁磿x擇現(xiàn)在這樣的線程方案 本文包括以下內(nèi)容

單線程規(guī)則 Swing線程在同一時刻僅能被一個線程所訪問 一般來說 這個線程是事件派發(fā)線程 規(guī)則的例外 有些操作保證是線程安全的 事件分發(fā) 假如你需要從事件處理或繪制代碼以外的地方訪問UI 那么你可以使用SwingUtilities類的invokeLater要求在事件派發(fā)線程中執(zhí)行某些代碼 這個方法會立即返回 不會等待代碼執(zhí)行完畢 invokeAndWait行為與invokeLater類似 除了這個方法會等待代碼執(zhí)行完畢 一般地 你可以用invokeLater來代替這個方法 下面是一些使用這幾個API的例子 請同時參閱《TheJavaTutorial》中的 BINGOexample 尤其是以下幾個類 CardWindow ControlPane Player和OverallStatusPane

使用invokeLater方法你可以從任何線程調(diào)用invokeLater方法以請求事件派發(fā)線程運行特定代碼 你必須把要運行的代碼放到一個Runnable對象的run方法中 并將此Runnable對象設(shè)為invokeLater的參數(shù) invokeLater方法會立即返回 不等待事件派發(fā)線程執(zhí)行指定代碼 這是一個使用invokeLater方法的例子

 RunnabledoWorkRunnable=newRunnable };

SwingUtilities invokeLater;使用invokeAndWait方法invokeAndWait方法和invokeLater方法很相似 除了invokeAndWait方法會等事件派發(fā)線程執(zhí)行了指定代碼才返回 在可能的情況下 你應(yīng)該盡量用invokeLater來代替invokeAndWait 假如你真的要使用invokeAndWait 請確保調(diào)用invokeAndWait的線程不會在調(diào)用期間持有任何其他線程可能需要的鎖

這是一個使用invokeAndWait的例子

 voidshowHelloThereDialogthrowsException }; SwingUtilities invokeAndWait; }

類似地 假設(shè)一個線程需要對GUI的狀態(tài)進行存取 比如文本域的內(nèi)容 它的代碼可能類似這樣

 voidprintTextField throwsException }; SwingUtilities invokeAndWait; System out println;}

假如你能避免使用線程 最好這樣做 線程可能難于使用 并使得程序的debug更困難 一般來說 對于嚴(yán)格意義下的GUI工作 線程是不必要的 比如對組件屬性的更新 不管怎么說 有時候線程是必要的 下列情況是使用線程的一些典型情況 執(zhí)行一項費時的任務(wù)而不必將事件派發(fā)線程鎖定 例子包括執(zhí)行大量計算的情況 會導(dǎo)致大量類被裝載的情況 和為網(wǎng)絡(luò)或磁盤I/O而阻塞的情況 重復(fù)地執(zhí)行一項操作 通常在兩次操作間間隔一個預(yù)定的時間周期 要等待來自客戶的消息 你可以使用兩個類來幫助你實現(xiàn)線程 SwingWorker 創(chuàng)建一個后臺線程來執(zhí)行費時的操作 Timer 創(chuàng)建一個線程來執(zhí)行或多次執(zhí)行某些代碼 在兩次執(zhí)行間間隔用戶定義的延遲 使用SwingWorker類SwingWorker類在SwingWorker java中實現(xiàn) 這個類并不包含在Java的任何發(fā)行版中 所以你必須單獨下載它 SwingWorker類做了所有實現(xiàn)一個后臺線程所需的骯臟工作 雖然許多程序都不需要后臺線程 后臺線程在執(zhí)行費時的操作時仍然是很有用的 它能提高程序的性能觀感

SwingWorkersanexampleofusingSwingWorker 要使用SwingWorker類 你首先要實現(xiàn)它的一個子類 在子類中 你必須實現(xiàn)construct方法還包含你的長時間操作 當(dāng)你實例化SwingWorker的子類時 SwingWorker創(chuàng)建一個線程但并不啟動它 你要調(diào)用你的SwingWorker對象的start方法來啟動線程 然后start方法會調(diào)用你的construct方法 當(dāng)你需要construct方法返回的對象時 可以調(diào)用SwingWorker類的get方法 這是一個使用SwingWorker類的例子

  //在main方法中 finalSwingWorkerworker=newSwingWorker }; worker start; //在動作事件處理方法中 JOptionPane showMessageDialog)

當(dāng)程序的main方法調(diào)用start方法 SwingWorker啟動一個新的線程來實例化ExpensiveDialogComponent main方法還構(gòu)造了由一個窗口和一個按鈕組成的GUI 當(dāng)用戶點擊按鈕 程序?qū)⒆枞?假如必要 阻塞到ExpensiveDialogComponent創(chuàng)建完成 然后程序顯示一個包含ExpensiveDialogComponent的模式對話框 你可以在MyApplication java找到整個程序 使用Timer類Timer類通過一個ActionListener來執(zhí)行或多次執(zhí)行一項操作 你創(chuàng)建定時器的時候可以指定操作執(zhí)行的頻率 并且你可以指定定時器的動作事件的監(jiān)聽者 啟動定時器后 動作監(jiān)聽者的actionPerformed方法會被調(diào)用來執(zhí)行操作 定時器動作監(jiān)聽者定義的actionPerformed方法將在事件派發(fā)線程中調(diào)用 這意味著你不必在其中使用invokeLater方法 這是一個使用Timer類來實現(xiàn)動畫循環(huán)的例子

 publicclassAnimatorApplicationTimer extendsJFrameimplementsActionListener publicvoidstartAnimationelse } publicvoidstopAnimation publicvoidactionPerformed }

在一個線程中執(zhí)行所有的用戶界面代碼有這樣一些優(yōu)點 組件開發(fā)者不必對線程編程有深入的理解 像ViewPoint和Trestle這類工具包中的所有組件都必須完全支持多線程訪問 使得擴展非常困難 尤其對不精通線程編程的開發(fā)者來說 最近的一些工具包如SubArctic和IFC 都采用和Swing類似的設(shè)計 事件以可預(yù)知的次序派發(fā) invokeLater排隊的runnable對象從鼠標(biāo)和鍵盤事件 定時器事件 繪制請求的同一個隊列派發(fā) 在一些組件完全支持多線程訪問的工具包中 組件的改變被變化無常的線程調(diào)度程序穿插到事件處理過程中 這使得全面測試變得困難甚至不可能 更低的代價 嘗試小心鎖住臨界區(qū)的工具包要花費實足的時間和空間在鎖的治理上 每當(dāng)工具包中調(diào)用某個可能在客戶代碼中實現(xiàn)的方法時 工具包都要保存它的狀態(tài)并釋放所有鎖 以便客戶代碼能在必要時獲得鎖 當(dāng)控制權(quán)交回到工具包 工具包又必須重新抓住它的鎖并恢復(fù)狀態(tài) 所有應(yīng)用程序都不得不負(fù)擔(dān)這一代價 即使大多數(shù)應(yīng)用程序并不需要對GUI的并發(fā)訪問 這是的SubArcticJavaToolkit的對在工具包中支持多線程訪問的問題的描述 我們的基本信條是 當(dāng)設(shè)計和建造多線程應(yīng)用程序 尤其是那些包括GUI組件的應(yīng)用程序時 必須保證極端小心 線程的使用可能會很有欺騙性 在許多情況下 它們表現(xiàn)得能夠極好的簡化編成 使得設(shè)計 專注于單一任務(wù)的簡單自治實體 成為可能 在一些情況下它們的確簡化了設(shè)計和編碼 然而 在幾乎所有的情況下 它們都使得調(diào)試 測試和維護的困難大大增加甚至成為不可能 無論大多數(shù)程序員所受的練習(xí) 他們的經(jīng)驗和實踐 還是我們用來幫助自己的工具 都不是能夠用來對付非決定論的 例如 全面測試在bug依靠于時間時是幾乎不可能的 尤其對于Java來說 一個程序要運行在許多不同類型的機器的操作系統(tǒng)平臺上 并且每個程序都必須在搶先和非搶先式調(diào)度下都能正常工作 由于這些固有的困難 我們力勸你三思是否絕對有使用線程的必要 盡管如此 有些情況下使用線程是必要的 所以subArctic提供了一個線程安全的訪問機制

lishixinzhi/Article/program/Java/gj/201311/27616

文章題目:線程安全問題java代碼 線程安全問題java代碼是什么
網(wǎng)頁路徑:http://jinyejixie.com/article24/hpcdce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、網(wǎng)站策劃網(wǎng)站制作、網(wǎng)站維護商城網(wǎng)站、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站