簡體   English   中英

Java線程:使用ArrayList的Wait Notify機制

[英]Java Threads: Wait Notify mechanism with ArrayList

我嘗試使用兩個單獨的線程來實現wait / notify機制來修改ArrayList

它似乎在第一次迭代時工作正常但在第二次迭代時它會在addToArray()方法中永遠等待。 我無法弄清楚為什么它在方法中永遠等待? 根據我的理解,其他線程(刪除項目)應該在其他線程等待時獲取。

如果有的話,請查看並指出可能的錯誤。 我知道我可以使用Vector來進行線程安全操作,但這不是我想要的。

package threadTest;
import java.util.*;

public class DhagaJava {

    public static void main(String...strings){
        ArrayModification am = new ArrayModification();

        Thread t1 = new Thread(new AddToArray(am));
        Thread t2 = new Thread(new RemoveFromArray(am));
        t1.start();
        t2.start();
    }
}

class ArrayModification{
    boolean added = false;
    ArrayList<Integer> al;

    ArrayModification(){
        al = new ArrayList<Integer>();
    }

    public synchronized void addToArrayList(int x) {
        if (added == true){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.al.add(x);
        System.out.println(al);
        System.out.println("Added!! :)");
        added = true;
        notifyAll();
    }

    public synchronized void removeFromList(){
        if( added== false){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(al);     
        this.al.remove(0);
        System.out.println("Removed!! :' ");
        added = false;
        notifyAll();
    }
}

class AddToArray implements Runnable{

    ArrayModification ma;

    AddToArray(ArrayModification m){
        this.ma = m;
    }

    public void run() { 
        for (int i = 0; i<10; i++)
            ma.addToArrayList(i);
    }
}

class RemoveFromArray implements Runnable{

    ArrayModification ma;

    RemoveFromArray(ArrayModification a){
        this.ma = a;
    }

    public void run(){
            ma.removeFromList();
    }
}

class RemoveFromArray implements Runnable{

      ArrayModification ma;

      RemoveFromArray(ArrayModification a){
            this.ma = a;
      }

      public void run(){
            //for(int j=11;j<20; j++)
                  ma.removeFromList();
      }
}

輸出是:

[0]
Added!! :)
[0]
Removed!! :' 
[1]
Added!! :)

不要重新發明輪子,只需使用CopyOnWriteArrayList 它具有開箱即用的並發性。

唯一的問題是removeFromList只運行一次(因為你推薦了for循環)。 這就是為什么日志中沒有第二次刪除並且addToArrayList開始等待的原因(等待某人從列表中刪除該項目)。

刪除評論后我嘗試了你的代碼,工作正常!

您的notifyAll位於synchronized塊內。 所以另一個線程可能會在他行動之前被喚醒。 所以它可能被阻止。

我不確定我理解你的目標,但這種結構可能更好:

public void addToArrayList(int x) {
    synchonized(this.al) {
        if (added == true){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.al.add(x);
        System.out.println(al);
        System.out.println("Added!! :)");
        added = true;
    }
    notifyAll();
}

但這非常復雜。 你有更普遍的目標嗎? 也許只有一個線程的任務隊列可以更好地適合你:它會更快,更輕,更簡單,並且可以並行化(根本不是)。

暫無
暫無

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

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