導航:首頁 > 編程語言 > java臟數據

java臟數據

發布時間:2022-04-22 08:52:53

❶ 請問java中的臟數據是指什麼

「臟數據 」在很多地方都有出現比如:資料庫,MFC的文檔設置中。通常臟數據是表示一個數據已經被修改,但是還沒有保存或進一步的處理。比如在MFC的文檔中當你把一個文檔設置成由臟數據時假如你退出程序,就會提示你是否保存修改當數據。
臟數據 一般就是一個標志,數據被修改了。

❷ 如何避免Java程序中的數據臟讀問題

臟讀就是指讀到還沒完全弄好的數據。比如,你要讀取資料庫中的欄位A、欄位B,你讀取時恰巧有其他用戶正在更新這2個欄位,而且是先更新A、再更新B,此時就可能會發生臟讀:
1、如果都未更新你就讀取了,或者都更新完了你才讀取,這都不是臟讀,因為你得到的是更新前的有效值,或完全更新後的值。
2、如果那個用戶更新一半你就讀取了,也就是說更新了A,正打算要更新B但尚未更新時,你就讀取了,此時你得到的就是臟數據。
避免臟讀的辦法就是採取事務,使得他用戶正在更新時鎖定資料庫,阻止你讀取,直至全部完成才讓你讀取。

❸ 臟數據,用JAVA怎麼處理

事務沒有控制好,a線程更新了數據,也commit了,但是b線程讀取到了更新後的值,但是此時a線程發生了回滾,那麼b線程讀到的值就是錯誤的,這種情況要控制好並發更新db的操作。
控制在同一個事務內實現並行操作。

❹ java 臟讀臟寫 怎麼產生的

產生臟數據,是因為多線程的原因,當某一個正在寫數據時,另一個線程讀取的數據是不準確的,需要進行同步處理。

❺ JAVA的哪些異常不應該被捕獲

異常都應該事先考慮過,
只是捕獲後可以選擇跳過處理,
只要不影響程序設計的初衷。

下面是幾種常見的異常;
1、算術異常(ArithmeticException)
2、沒有給對象開辟內存空間時會出現空指針異常(NullPointerException)
3、找不到文件異常(FileNotFoundException)

❻ java是線程安全的嗎

線程安全就是多線程訪問時,採用了加鎖機制,當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。不會出現數據不一致或者數據污染。(Vector,HashTab;le)
線程不安全就是不提供數據訪問保護,有可能出現多個線程先後更改數據造成所得到的數據是臟數據。(ArrayList,LinkedList,HashMap等)
概念:
如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是線程安全的。或者說:一個類或者程序所提供的介面對於線程來說是原子操作或者多個線程之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題。線程安全問題都是由全局變數及靜態變數引起的。
若每個線程中對全局變數、靜態變數只有讀操作,而無寫操作,一般來說,這個全局變數是線程安全的;若有多個線程同時執行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。
例子:
比如一個 ArrayList 類,在添加一個元素的時候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在單線程運行的情況下,如果 Size = 0,添加一個元素後,此元素在位置 0,而且 Size=1;
而如果是在多線程情況下,比如有兩個線程,線程 A 先將元素存放在位置 0。但是此時 CPU 調度線程A暫停,線程 B
得到運行的機會。線程B也向此 ArrayList 添加元素,因為此時 Size 仍然等於 0
(注意哦,我們假設的是添加一個元素是要兩個步驟哦,而線程A僅僅完成了步驟1),所以線程B也將元素存放在位置0。然後線程A和線程B都繼續運行,都增加
Size 的值。
那好,我們來看看 ArrayList 的情況,元素實際上只有一個,存放在位置 0,而 Size 卻等於 2。這就是「線程不安全」了。
安全性:
線程安全性不是一個非真即假的命題。 Vector 的方法都是同步的,因為java會有相應的機制是同一時刻只有一個線程對這個變數操作。並且
Vector 明確地設計為在多線程環境中工作。但是它的線程安全性是有限制的,即在某些方法之間有狀態依賴(類似地,如果在迭代過程中 Vector
被其他線程修改,那麼由 Vector.iterator() 返回的
iterator會拋出)。
對於 Java 類中常見的線程安全性級別,沒有一種分類系統可被廣泛接受,不過重要的是在編寫類時盡量記錄下它們的線程安全行為。
Bloch 給出了描述五類線程安全性的分類方法:不可變、線程安全、有條件線程安全、線程兼容和線程對立。只要明確地記錄下線程安全特性,那麼您是否使用這種系統都沒關系。這種系統有其局限性
– 各類之間的界線不是百分之百地明確,而且有些情況它沒照顧到 –
但是這套系統是一個很好的起點。這種分類系統的核心是調用者是否可以或者必須用外部同步包圍操作(或者一系列操作)。下面幾節分別描述了線程安全性的這五種類別。
不可變
不可變的對象一定是線程安全的,並且永遠也不需要額外的同步。因為一個不可變的對象只要構建正確,其外部可見狀態永遠也不會改變,永遠也不會看到它處於不一致的狀態。Java
類庫中大多數基本數值類如 Integer 、 String 和 BigInteger 都是不可變的。
需要注意的是,對於Integer,該類不提供add方法,加法是使用+來直接操作。而+操作是不具線程安全的。這是提供原子操作類AtomicInteger的原。
線程安全
線程安全的對象具有在上面「線程安全」一節中描述的屬性 –
由類的規格說明所規定的約束在對象被多個線程訪問時仍然有效,不管運行時環境如何排線程都不需要任何額外的同步。這種線程安全性保證是很嚴格的 –
許多類,如 Hashtable 或者 Vector 都不能滿足這種嚴格的定義。
有條件的線程安全
有條件的線程安全類對於單獨的操作可以是線程安全的,但是某些操作序列可能需要外部同步。條件線程安全的最常見的例子是遍歷由 Hashtable
或者 Vector 或者返回的迭代器 – 由這些類返回的 fail-fast
迭代器假定在迭代器進行遍歷的時候底層集合不會有變化。為了保證其他線程不會在遍歷的時候改變集合,進行迭代的線程應該確保它是獨占性地訪問集合以實現遍歷的完整性。通常,獨占性的訪問是由對鎖的同步保證的
– 並且類的文檔應該說明是哪個鎖(通常是對象的內部監視器(intrinsic monitor))。
如果對一個有條件線程安全類進行記錄,那麼您應該不僅要記錄它是有條件線程安全的,而且還要記錄必須防止哪些操作序列的並發訪問。用戶可以合理地假設其他操作序列不需要任何額外的同步。
線程兼容
線程兼容類不是線程安全的,但是可以通過正確使用同步而在並發環境中安全地使用。這可能意味著用一個 synchronized
塊包圍每一個方法調用,或者創建一個包裝器對象,其中每一個方法都是同步的(就像 Collections.synchronizedList()
一樣)。也可能意味著用 synchronized
塊包圍某些操作序列。為了最大程度地利用線程兼容類,如果所有調用都使用同一個塊,那麼就不應該要求調用者對該塊同步。這樣做會使線程兼容的對象作為變數實例包含在其他線程安全的對象中,從而可以利用其所有者對象的同步。
許多常見的類是線程兼容的,如集合類 ArrayList 和 HashMap 、 java.text.SimpleDateFormat 、或者 JDBC 類 Connection 和 ResultSet 。
線程對立
線程對立類是那些不管是否調用了外部同步都不能在並發使用時安全地呈現的類。線程對立很少見,當類修改靜態數據,而靜態數據會影響在其他線程中執行的其他類的行為,這時通常會出現線程對立。線程對立類的一個例子是調用 System.setOut() 的類。

❼ java之用volatile和不用volatile的區別

在當前的Java內存模型下,線程可以把變數保存在本地內存(比如機器的寄存器)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變數的值,而另外一個線程還繼續使用它在寄存器中的變數值的拷貝,造成數據的不一致。
要解決這個問題,只需要像在本程序中的這樣,把該變數聲明為volatile(不穩定的)即可,這就指示JVM,這個變數是不穩定的,每次使用它都到主存中進行讀取。一般說來,多任務環境下各任務間共享的標志都應該加volatile修飾。

Volatile修飾的成員變數在每次被線程訪問時,都強迫從共享內存中重讀該成員變數的值。而且,當成員變數發生變化時,強迫線程將變化值回寫到共享內存。這樣在任何時刻,兩個不同的線程總是看到某個成員變數的同一個值。
用volatile和不用volatile的區別,運行一下,就知道了。
不用volatile:
package com.keyword;
public class TestWithoutVolatile {
private static boolean bChanged;
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
for (;;) {
if (bChanged == !bChanged) {
System.out.println("!=");
System.exit(0);
}
}
}
}.start();
Thread.sleep(1);
new Thread() {
@Override
public void run() {
for (;;) {
bChanged = !bChanged;
}
}
}.start();
}

}
運行後,程序進入死循環了,一直在運行。

用volatile:

package com.keyword;
public class TestWithVolatile {
private static volatile boolean bChanged;

public static void main(String[] args) throws InterruptedException {
new Thread() {

@Override
public void run() {
for (;;) {
if (bChanged == !bChanged) {
System.out.println("!=");
System.exit(0);
}
}
}
}.start();
Thread.sleep(1);
new Thread() {

@Override
public void run() {
for (;;) {
bChanged = !bChanged;
}
}
}.start();
}

}

程序輸出!=,然後馬上退出。
但是,很多情況下,用不用volatile,感覺不出什麼區別,什麼時候要用volatile呢?看看JDK里使用volatile的類。
比如java.util.regex.Pattern里的變數:
private transient volatile boolean compiled = false;
還有,java.lang.System的變數:
private static volatile Console cons = null;
一般就是初始化的時候,需要用到volatile。
java.util.Scanner里的變數,如:
private static volatile Pattern boolPattern;
private static volatile Pattern separatorPattern;
private static volatile Pattern linePattern;
初始化boolPattern的代碼:
private static Pattern boolPattern() {
Pattern bp = boolPattern;
if (bp == null)
boolPattern = bp = Pattern.compile(BOOLEAN_PATTERN,
Pattern.CASE_INSENSITIVE);
return bp;
}
上面的情況,可以使用synchronized來對boolPattern加鎖,但是synchronized開銷比volatile大,volatile能夠勝任上面的工作。
volatile不保證原子操作,所以,很容易讀到臟數據。
使用建議:在兩個或者更多的線程訪問的成員變數上使用volatile。當要訪問的變數已在synchronized代碼塊中,或者為常量時,不必使用。

❽ java怎麼防止臟數據

你好 這種情況是你假想出來的么? 數據來源是什麼 如果是資料庫 那麼實際情況會是這樣
兩個人同時訪問到的數據 都是100 同時加上50 那麼是兩條不同的sql語句 實際的sql語句肯定會帶條件的 不會簡簡單單的 update xx set a=a+50 這么簡單的 如果你的資料庫是這樣設計的 那麼請 附帶一個操作流水號 自己建立一個自增表 每次訪問往自增表插入一條數據 返回自增列 插入的值 可以是你的200 規定不允許重復 如果重復則分配自增號失敗 這樣子保證 插入的唯一性 流水號表
兩列
id identity(1,1) primary key 主鍵
num int unique確保唯一 是查詢到的那個值 也就是100
只要得不到自增號就不允許插入

❾ Java中如何保證線程安全性

並發(concurrency)一個並不陌生的詞,簡單來說,就是cpu在同一時刻執行多個任務。

而Java並發則由多線程實現的。

在jvm的世界裡,線程就像不相乾的平行空間,串列在虛擬機中。(當然這是比較籠統的說法,線程之間是可以交互的,他們也不一定是串列。)

多線程的存在就是壓榨cpu,提高程序性能,還能減少一定的設計復雜度(用現實的時間思維設計程序)。

這么說來似乎線程就是傳說中的銀彈了,可事實告訴我們真正的銀彈並不存在。

多線程會引出很多難以避免的問題, 如死鎖,臟數據,線程管理的額外開銷,等等。更大大增加了程序設計的復雜度。

但他的優點依舊不可替代。

死鎖和臟數據就是典型的線程安全問題。

簡單來說,線程安全就是:在多線程環境中,能永遠保證程序的正確性。

只有存在共享數據時才需要考慮線程安全問題。

java內存區域:

其中,方法區和堆就是主要的線程共享區域。那麼就是說共享對象只可能是類的屬性域或靜態域。

了解了線程安全問題的一些基本概念後, 我們就來說說如何解決線程安全問題。我們來從一個簡單的servlet示例來分析:

1. 了解業務場景的線程模型

這里的線程模型指的是: 在該業務場景下, 可能出現的線程調用實況。

眾所周知,Servlet是被設計為單實例,在請求進入tomcat後,由Connector建立連接,再講請求分發給內部線程池中的Processor,

此時Servlet就處於一個多線程環境。即如果存在幾個請求同時訪問某個servlet,就可能會有幾個線程同時訪問該servlet對象。如圖:

線程模型,如果簡單的話,就在腦海模擬一下就好了,復雜的話就可以用紙筆或其他工具畫出來。

2. 找出共享對象

這里的共享對象就很明顯就是ReqCounterServlet。

3. 分析共享對象的不變性條件

不變性條件,這個名詞是在契約式編程的概念中的。不變性條件保證類的狀態在任何功能被執行後都保持在一個可接受的狀態。

這里可以引申出,不可變對象是線程安全的。(因為不可變對象就沒有不變性條件)

不變性條件則主要由對可變狀態的修改與訪問構成。

這里的servlet很簡單, 不變性條件大致可以歸納為: 每次請求進入時count計數必須加一,且計數必須正確。

在復雜的業務中, 類的不變性條件往往很難考慮周全。設計的世界是險惡的,只能小心謹慎,用測量去證明,最大程度地減少錯誤出現的幾率。

4. 用特定的策略解決線程安全問題。

如何解決的確是該流程的重點。目前分三種方式解決:

第一種,修改線程模型。即不在線程之間共享該狀態變數。一般這個改動比較大,需要量力而行。

第二種,將對象變為不可變對象。有時候實現不了。

第三種,就比較通用了,在訪問狀態變數時使用同步。 synchronized和Lock都可以實現同步。簡單點說,就是在你修改或訪問可變狀態時加鎖,獨占對象,讓其他線程進不來。

這也算是一種線程隔離的辦法。(這種方式也有不少缺點,比如說死鎖,性能問題等等)

其實有一種更好的辦法,就是設計線程安全類。《代碼大全》就有提過,問題解決得越早,花費的代價就越小。

是的,在設計時,就考慮線程安全問題會容易的多。

首先考慮該類是否會存在於多線程環境。如果不是,則不考慮線程安全。

然後考慮該類是否能設計為不可變對象,或者事實不可變對象。如果是,則不考慮線程安全

最後,根據流程來設計線程安全類。

設計線程安全類流程:

1、找出構成對象狀態的所有變數。

2、找出約束狀態變數的不變性條件。

3、建立對象狀態的並發訪問管理策略。

有兩種常用的並發訪問管理策略:

1、java監視器模式。 一直使用某一對象的鎖來保護某狀態。

2、線程安全委託。將類的線程安全性委託給某個或多個線程安全的狀態變數。(注意多個時,這些變數必須是彼此獨立,且不存在相關聯的不變性條件。)

❿ Java中為什麼說多線程環境就不安全

先來給你舉個栗子幫你理解一下:
你是一個流浪漢,整天為飢餓發愁。有一天你發現了一個房間,這個房間里有很多食物,你很開心,你去品嘗食物。但是好景不長,很快又有很多流浪漢也發現了這里,他們也來這個房間去吃食物,你不能阻擋他們。你很不爽,同時原來被整整齊齊擺放的食物,他們來了就狼吞虎咽,食物被整的亂七八糟。
上面這個例子就是一個由單線程到多線程的問題,你一個人就是單線程,食物就是數據,你一個人可以處理數據,處理完了它就是那樣,不可能由其他的線程來修改數據。但是一旦到多線程環境(很多流浪漢),多線程同樣有操作數據的權力,他們可以任意修改數據,這樣數據就可能被修改很多次,從而發生臟數據(食物亂七八糟),這樣的數據就是不安全的,返回給前台用就有可能發生錯亂,出來的結果與業務邏輯不符。
怎麼避免這個問題呢,也就是解決多線程問題,可以定義一個鎖,加上synchronize關鍵字,鎖住一個代碼塊,這樣就算有很多人去搶同一個資源,有鎖的話,一個人進去,把門關上,鎖住,其他人就進不來了。這個人消耗了資源,然後再出來,下一個再進去。這樣就避免哄搶的問題。還有更有效的方式是使用線程池,可以有效解決線程安全問題。

閱讀全文

與java臟數據相關的資料

熱點內容
linux打包命令targz 瀏覽:996
抖音app是哪個 瀏覽:407
蘋果app怎麼上架 瀏覽:255
NA伺服器地址 瀏覽:427
我的世界如何初始化伺服器 瀏覽:97
哪個手機app天氣預報最准 瀏覽:752
怎樣把視頻壓縮至25m 瀏覽:570
vivox27文件夾怎麼改變 瀏覽:727
新手玩狼人殺用什麼app 瀏覽:615
pdf在線查看 瀏覽:954
安卓tv90如何關閉後台 瀏覽:683
php讀取word亂碼 瀏覽:755
minicom源碼 瀏覽:1001
海爾冷櫃壓縮機 瀏覽:416
聯通伺服器如何調試信號 瀏覽:136
stata新命令 瀏覽:941
單調棧演算法python 瀏覽:606
微信解壓游戲怎麼下載 瀏覽:962
忍三伺服器不同如何登上賬號 瀏覽:822
php求積 瀏覽:297