簡體   English   中英

我必須在哪里使用同步?

[英]Where do i have to use synchronized?

我已經進行了一些研究,找不到解決此問題的方法。

從本主題同步,何時使用或不使用? 我知道我可以使用synchronized ,但是這樣做不能解決問題。

這種情況是我有一種方法,其中使用一個Thread來創建ArrayList 在同一Thread ,在BufferedReader完成讀取文件並將行添加到第一個List之后,將調用另一個method

在第二種方法中,第一個列表用於創建第二個列表。 完成所有操作后,第一種方法將使用第二個列表。

這是我使用的代碼,如果有不清楚的地方,請詢問,我將嘗試提供所需的信息。

public synchronized void theBaseList() {
    Thread t = new Thread() {
        @override
        public void run() {
          try(
              while((line = br.readLine()) != null) {
                  firstList.add(line):
              }
          }
          nextMethod();
          currentObject = (Object[]) secondList.get(0); // throws an exception
          }
      }
  };
  t.start();

public synchronized void nextMethod() {
    Thread t1 = new Thread(){
        double objectListSize = calculateObjectListLength(firstList.size());
        @override
        public void run() {
          try {
              // create Objects
              secondList.add(objects);
            }
         }
      };
      t1.start();
}

當我在nextMethod()使用Thread從第一個list中的項目創建對象的新list時,我得到了ArrayIndexOutOfBoundsException

線程“ Thread-4”中的異常java.lang.IndexOutOfBoundsException:索引:0,大小:0

我通過在第二種方法中不使用Thread來避免這種情況,並且一切正常。

如果我確實使用2個Threads並使兩個方法synchronized ,它仍然會引發異常。

是否有可能或者應該通過在第二種方法中不使用Thread來解決問題? 我認為synchronized是用於處理此類問題的。 我不明白為什么它不起作用。

假設您的方法是在名為Sample的類中定義的,並且已經創建了一個mySample實例。 這似乎是您的代碼正在執行的操作:

main thread calls mySample.theBaseList() and synchronizes by locking on mySample.
  theBaseList() defines thread1 and starts it.
  theBaseList() exits scope, thus unlocking on mySample.

thread1 reads in the lines of a file and adds them to list1 (these operations are not synchronized)
thread1 calls mySample.nextMethod()
mySample.nextMethod() synchronizes by locking on mySample
    nextMethod() defines thread2 and starts it.
    nextMethod() exits scope, thus unlocking on mySample.

* thread2 sets up list2 (these operations are not synchronized)
* thread1, having returned from nextMethod() reads from list2 (these operations are not synchronized)

最后兩個操作是導致您的比賽狀況的原因。

在您的情況下,使用同步方法可能過於粗糙。 更好的選擇可能是在兩個線程都在其上操作的對象secondList上進行同步。

nextMethod();
synchronized(secondList) {
    currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}

synchronized(secondList) {
    // create Objects
    secondList.add(objects);
}

編輯:

synchronized(secondList) {
    nextMethod();
    secondList.wait();
    currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}

synchronized(secondList) {
    // create Objects
    secondList.add(objects);
    secondList.notifyAll();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM