2012-04-10 22 views
0

我有一個方法,調度程序每分鐘調用一次從ftp獲取文件,處理並將其記錄保存到數據庫。我需要這個線程安全的,這樣,如果該方法能同時執行多個文件,它充當一個在一個線程安全的方式..制定一個預定的方法線程安全

public synchronized void processData(String data){ 
    //do processing 
} 

,這真的會是將要處理的線程安全的方法大量的負載優雅?

+0

在我的場景中,讓我們想象一下在11點調用調度程序,該程序會在processData方法中處理1000個文件。調度程序配置爲每隔1分鐘執行一次,並在11:01中再次調用,但是最初的1000個文件的處理未完成。解決這種情況的最佳方法是什麼? 1.消除方法中的同步關鍵字 2.爲每個文件進程啓動一個新線程 ? – Sanath 2012-04-10 04:07:49

回答

3

只要它不使用封閉對象中的任何有狀態字段,它就是線程安全的。

換句話說,如果有一個在processData(String data)中操作或訪問的類級字段,目的是跟蹤正在發生的事情,那麼它不是線程安全的。

一個例子可能是一個名爲private Boolean hasConnection;的類級別字段如果您需要檢查該字段是否存在連接,那麼您沒有線程安全方法。

如果您符合此要求,那麼您甚至不必將​​關鍵字添加到您的方法中。默認情況下,它將是線程安全的,並且無限數量的線程可以同時訪問它。

如果你不符合這個要求,那麼你將需要發佈整個班級,以確定它是否是線程安全的。

+1

使用對象實例爲鎖定在方法級別上未同步?意思是說,所有的實例級別的字段都受到保護...... – rfeak 2012-04-10 03:28:54

+0

@rfeak它們不一定受到保護。如果他們是「公共」,他們絕對不受保護。如果他們是'私人',但通過非'同步'方法訪問,他們也不受保護。 – 2012-04-10 03:30:43

+0

我想保護是錯誤的方式來說。同步方法使用鎖對象。這意味着對象實例中的變量不能同時被多個線程訪問,對於THAT方法(或任何其他在該類上標記爲同步的方法)。我的觀點是,只要您標記可能會更改狀態的其他同步方法,您就可以使用該方法中的實例變量。 – rfeak 2012-04-10 03:32:16

2

假設神祕的「處理文件」操作是獨立的,您應該擔心的最重要的事情是數據庫連接:不要讓它共享,每次從連接字符串獲取一個新連接,並使用一個connection pool。不要讓你的方法同步,除非你需要在你的類中訪問共享狀態;否則,您的方法將無法在多個線程上同時取得進展。

1

請描述您的方法使用哪些資源以及共享哪些資源。

如果你不使用普通對象,這是沒有問題的。

如果您確實使用公共資源,則需要確保可以以線程安全的方式訪問這些資源,或者不會被多個線程訪問。

你的問題是關於性能。通常,processData似乎是需要一些時間才能完成的一種方法:您正在使用數據庫。與DB查詢相比,獲得鎖定所需的時間很少。所以不,​​關鍵字不會給你帶來任何明顯的性能影響。