2013-07-27 28 views
5

Tôi đang tạo một chương trình trong đó một nhóm x số lượng chủ đề tương tác với một khoảng không quảng cáo được chia sẻ. Trong trường hợp này, tôi sử dụng ArrayList làm khoảng không quảng cáo được chia sẻ. Trong chương trình của tôi, các chủ đề đại diện cho các công việc mà một sinh vật có. Sinh vật thuộc về một bên và chia sẻ một nhóm các đồ tạo tác được sử dụng để thực hiện công việc. chỉ có một sinh vật tôi tương tác với hồ bơi bất cứ lúc nào.Các chủ đề không liên lạc

Vì một lý do nào đó, tôi tiếp tục gặp sự cố với truyền thông chuỗi. Tôi đã thiết lập nó vì vậy nếu hồ bơi không được sử dụng các sinh vật giọt tất cả các mục của nó vào hồ bơi và bắt đầu xem xét thông qua nó. Và nếu họ không thể tìm thấy mọi thứ họ cần họ nên thả tất cả các hiện vật mà họ có vào hồ bơi, Đặt hồ bơi để không bận, sau đó báo hiệu một sinh vật chờ đợi trên hồ bơi mà nó đã sẵn sàng để họ đi qua nó cũng.

Vấn đề của tôi là nếu một sinh vật nhìn qua hồ bơi trong khi người khác đang chờ đợi, và nó không thể tìm thấy nó giống như nó lặp lại quá trình mà không thông báo hoặc để cho các sinh vật khác đi qua nó.

Tôi đã cố gắng: Ban đầu tôi đã thử sử dụng khóa nhưng khóa sẽ không báo hiệu chủ đề khác. Sau đó, tôi viết lại nó tận dụng lợi thế của đồng bộ (Đảng). Sau đó, tôi nghĩ rằng đó là bởi vì các chủ đề đã bị rơi một nơi nào đó nhưng một sợi có thể chạy tất cả các cách thông qua và thậm chí đổ các mục của nó trở lại vào hồ bơi khi công việc hoàn thành (cho một sinh vật đã không bị khóa hồ bơi thành limbo).

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
    //checks to see if creature already has correct amount of each item. 
    //If it does it should skip pool interaction until it dumps its used items 
    //back into the pool. 
    System.out.println("Ready: " + ready); 
    while (!ready) {//begin pool interaction 
     synchronized (target.poolParty){ 
      System.out.println("Ready: " + ready); 
      System.out.println(this); 
      while (target.poolParty.busyPool) {//busyPool is initialized false 
       startJob.setEnabled(false); 
       try { 
        target.poolParty.wait(); 
       } catch (InterruptedException e) {} 
      } 
      synchronized (target.poolParty) { 
       target.poolParty.busyPool = true; 
       target.poolParty.notifyAll();//notify all threads that they need to wait because this one will proceed 
      } 
     } 
     target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty 
            //then clears the creatures inventory 
     target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 

     ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
     if (ready) { 
      synchronized (target.poolParty) { 
       System.out.println("has required Items"); 
       target.poolParty.busyPool = false; 
       target.poolParty.notify(); 
      } 
     } else { 
      synchronized (target.poolParty) { 
       System.out.println("Does not has required Items"); 
       target.poolParty.busyPool = false; 
       target.releaseArtifacts(); 
       target.poolParty.notifyAll(); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e){} 
      } 
     } 
    }//end pool interaction 

Tôi thực hiện loại tương tác giữa các chủ đề trong trường hợp một sinh vật có nhiều công việc nhưng chỉ có thể thực hiện một công việc tại một thời điểm và hoạt động hoàn hảo. Tôi đã điều chỉnh các phương pháp đó để phù hợp với tình huống này và tôi vẫn gặp sự cố.

Lưu ý: Tôi rất mới đồng thời để tha thứ cho tôi nếu từ vựng của tôi không phát triển về chủ đề này.

Trả lời

1

Dường như bạn đang ngủ trong một khối sử dụng target.poolParty để đồng bộ hóa. Điều đó có nghĩa là các chủ đề khác đang chờ truy cập vào nhóm sẽ không thể truy cập được vì chuỗi này đang chặn nó. Di chuyển sleep() ra ngoài khối đó.

Ở một nơi khác bạn sử dụng synchronized (target.poolParty) trong một khối đã sử dụng để đồng bộ hóa. Điều đó là không cần thiết (tốt, toàn bộ khối mã là không cần thiết và tôi đã xóa nó. Chỉ cần chỉ ra). Ngoài ra, wait()notify*() là các nguyên tắc đồng bộ hóa cấp thấp và hiếm khi cần.

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
//checks to see if creature already has correct amount of each item. 
//If it does it should skip pool interaction until it dumps its used items 
//back into the pool. 
System.out.println("Ready: " + ready); 
while (!ready) { 
    // begin pool interaction 
    synchronized (target.poolParty) { 
     target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
     ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 

     /* I'd move this here. If we never release out items then the 
      other party members can't use them while this one still does 
      not have the needed items. Now they will be available to 
      other parties while this thread sleeps. */ 
     if (!ready) { 
      // adds all artifacts held by creature to an arraylist in poolParty 
      target.releaseArtifacts(); 
     } 
    } 

    // These don't access the pool, so they can be outside the synchronized block 
    if (ready) { 
     System.out.println("has required Items"); 
    } else { 
     System.out.println("Does not have required Items"); 
     // Sleep before the next try to get the required items. Lets other 
     // threads attempt to fetch their needed items 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // Added, because silently eating exceptions is a bad idea 
      e.printStackTrace(); 
     } 
    } 
}//end pool interaction 
+0

Cảm ơn bạn đã cố gắng giải thích lỗi của tôi cho tôi. Tôi đã có thể kết hợp những gì tôi đã học được từ điều này vào một số mã tôi đã có để hủy bỏ một công việc và giải phóng tài nguyên. –

1

Có vẻ như bạn đang suy nghĩ về vấn đề. Trường hợp sử dụng của bạn rất đơn giản.

  • Chỉ một sinh vật có thể truy cập vào hồ bơi tại bất kỳ thời điểm nào.
  • Các sinh vật khác phải đợi trong thời gian đó.
  • Tài nguyên được chia sẻ ở đây là hồ bơi.

Bây giờ đơn giản

synchronize(pool){ 
//doStuff 
} 

nên làm việc.

Lưu ý rằng wait()notify()/notifyAll() là cần thiết khi bạn cần phải đồng bộ hóa các phần mã khác nhau không độc đáo rơi vào khối logic liên tiếp.

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
//checks to see if creature already has correct amount of each item. 
//If it does it should skip pool interaction until it dumps its used items 
//back into the pool. 
System.out.println("Ready: " + ready); 
if (!ready) {//begin pool interaction 
    synchronized (target.poolParty){ 
     System.out.println("Ready: " + ready); 
     System.out.println(this); 
     startJob.setEnabled(false); 
    } 
    target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty 
           //then clears the creatures inventory 
    target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
    } 
}//end pool interaction 
Các vấn đề liên quan