下面的類包含同步的arraylist和兩個方法,一個是清除和添加arrayLIst,另一個是獲取串列。
public class Singleton {
private static Singleton singleton;
private List<String> strList = Collections.synchronizedList(new ArrayList<String>());
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
public void addElement(List<String> list) {
strList.clear();
strList.addAll(list);
}
public List<String> getStrList(){
return new ArrayList<>(strList);
}
}
當在兩個不同的執行緒中呼叫 addElement 和 getStrList 時,有時會得到空串列。
public class App
{
public static void main(String[] args) throws InterruptedException
{
final Singleton singleton = Singleton.getInstance();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0; i<100; i ) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i<=50) {
singleton.addElement(Arrays.asList("ONE"));
} else {
singleton.addElement(Arrays.asList("TWO"));
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0; i<100; i ) {
System.out.println(singleton.getStrList());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t2.start();
}
}
輸出:
[TWO]
[]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
[]
[TWO]
[TWO]
[TWO]
[TWO]
[TWO]
在兩者之間有回傳的空串列。當 getStrList 方法中的串列為空時,如何在不添加睡眠的情況下解決此問題?也在尋找更好的替代方法來實作這一目標。
uj5u.com熱心網友回復:
addElement 有兩個陳述句:
strList.clear(); //statement1
strList.addAll(list); //statement2
getStrList() 有一個宣告
這兩種方法都是非同步的,因此在執行緒 t2 呼叫System.out.println(singleton.getStrList())
執行緒 t1之前剛剛執行了陳述句 1,該陳述句正在清除串列,導致 t2 列印空串列。
為避免這種情況,您必須使addElement()andgetStrList()同步以解決問題。
public synchronized void addElement(List<String> list) {
strList.clear();
strList.addAll(list);
}
public synchronized List<String> getStrList(){
return new ArrayList<>(strList);
}
uj5u.com熱心網友回復:
我想問題是你的'void addElement(List)'方法。
它不同步。
執行緒 1 獲得優先級并執行到串列被清除的行。然后執行緒 2 獲取優先級并列印空串列的狀態。最后優先級回傳到執行緒 1 并添加專案。
同步 addElement 應該修復它。
uj5u.com熱心網友回復:
您可以將addElement方法替換為
public void addElement(List<String> list) {
List<String> newStrList = Collections.synchronizedList(new ArrayList<>(list));
strList = newStrList;
}
這樣串列將被替換,您將永遠不會看到處于空狀態的串列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/408207.html
標籤:
