簡體   English   中英

為什么在notifyAll()之后我的線程不會喚醒?

[英]Why won't my threads wake up after the notifyAll();

因此,我已經嘗試了幾個小時,現在可以確定它確實很簡單,或者只是我遺漏的一個簡單錯誤,但是我有一個三類程序,控件,帳戶和MyThreads。

我正在嘗試讓多線程(卡)修改單個帳戶,我正在嘗試使用監視器,因此一次只能有一個線程可以進行更改,這不是我存檔的內容,我以某種方式只允許一個線程訪問帳戶類,沒有其他類,它們似乎只是消失了,我認為它們只是等待中,但是拒絕喚醒...在我崩潰之前有什么幫助嗎?

帳號:

class account{
private static int value = 0;
private static int cards = 0;
private static int count = 0;
private static int lock = 0;


public void setValue(int temp){
value = temp;
}

public int getValue(){

//   while(lock == 1){
//    try{
//      wait();
//    }catch (InterruptedException e){
//    }
//  }
return value;
}

synchronized public void withdraw(int temp, String tempID){
while(lock == 1){
try{
wait();
}catch (InterruptedException e){}
}

lock=1;
value= value - temp;
count++;
System.out.println(count + "(" + tempID +")"+"  "+temp+"  -  "+value);
lock = 0;

this.notifyAll();

}


synchronized public void deposit(int temp, String tempID){
while(lock == 1){
try{
 wait();
}catch (InterruptedException e){}
}

lock=1;
value= value + temp;
count++;
System.out.println(count + "(" + tempID +")"+"  -  "+temp+"  "+value);
lock = 0;
this.notifyAll();
}

public void setCards(int temp){
cards = temp;
}


public int getCards(){
return cards;
}

public int getCount(){
return count;
 }
 }

控制代碼:

class control{

public static void main(String [] args){

account acc = new account();

acc.setValue(1000);

acc.setCards(5);


 //    if(args.length > 0){
 //      try{
 //       int tempCards = Integer.parseInt(args[0]);
 //       
 //      }catch (NumberFormatException e) {
 //        System.err.println("Number of Cards : " + args[0] + " must be an integer.");
//        System.exit(1);
//      }
//      try{
//        int tempVal = 0;
//        tempVal = Integer.parseInt(args[1]);
//        acc.setValue(tempVal);
//      }catch (NumberFormatException e) {
//        System.err.println("Account Value : " + args[1] + " must be an integer.");
//        System.exit(1);
//      }
//    }else{
//      System.err.println("No values found, please start program with the number of Cards and Bank Account Value, both in integer format");
//      System.exit(1);
//    }


System.out.println("Transaction  Withdrawal  Deposit  Balance");
System.out.println("                                  " + acc.getValue());

for(int i=0; i<=((acc.getCards())-1); i++){
new MyThreads(Integer.toString(i+1));

}
}
}

MyThreads代碼:

class MyThreads implements Runnable{
private String ID;
private Thread t;

account acc = new account();
MyThreads(String tempID){
ID = tempID;
t = new Thread(this, ID);
t.start();
}


public void run(){

try{

for (int i = 0; i < 20; i++){


  if(Math.random()>0.5){

    int tempW = 0;

    tempW = ((int)(Math.random()*100));

    acc.withdraw(tempW, this.ID);

    //System.out.println(acc.getCount() + "(" + this.ID +")"+"  "+tempW+"  -"+acc.getValue());

    }else{

    int tempD = 0;
    tempD = ((int)(Math.random()*100));
    acc.deposit(tempD, this.ID);
    //System.out.println(acc.getCount() + "(" + this.ID +")"+"  "+"  -  "+tempD+"  "+acc.getValue());

    }

    t.sleep(500);
    }
    } catch (InterruptedException e) {
     System.out.println("Thread " +  ID + " interrupted.");
    }
    System.out.println("Thread " +  ID + " exiting.");
    }

    }

我知道那是一團糟,請原諒我很懶。

看一下Java中Monitor的定義。 在您的代碼中,對兩個方法使用關鍵字synchronized ,它們與以下方法相同:

 public void XX(){
    lock.lock(); // lock is a private variable 
    try {
        // code here

    } finally {
        lock.unlock();
    }
 }

簡而言之,它是顯式鎖定的簡寫形式,它將阻止多個線程同時訪問方法。

因此,只需刪除synchronized方法中的lock部分(即while(lock==1)塊),它將起作用。 另外,如果在其他代碼中需要實鎖,請使用Lock類,而不要使用整數。

有關更多信息,網絡上有很多關於多線程的很好的介紹,例如this

您的問題(也是答案)是靜態同步和等待通知的絕妙組合,必須調用它。 為什么要使用靜態? 聽起來像個魔術字? 跳過靜態並簡化生活。

還請注意,等待通知與特定對象有關; 如果wait-notify與不同的對象相關,則它們將不會通信。 有一個他們都可以同步的對象。

暫無
暫無

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

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