2013-04-12 38 views
7

Tôi có một chuỗi xử lý vòng lặp trò chơi của mình, khi tôi gọi .join() trên chuỗi này, ứng dụng sẽ ngừng phản hồi. Tôi đã cố gắng khắc phục sự cố trong đó các chương trình không bao giờ nhận được mã, I.E chuỗi không bao giờ kết thúc.Android- Thread.join() khiến Ứng dụng treo

System.out.println("YAY"); 

Chủ đề của tôi dành cho Game Loop:

chủ đề này thành công in ra "Trò chơi kết thúc" nhưng không bao giờ dường như để kết thúc.

Runnable startGameLoop = new Runnable() {//game loop 
      @Override 
      public void run() { 

       AiFactory ai = new AiFactory(); 
       final Button play = (Button) findViewById(R.id.Play); 
       final Button pass = (Button) findViewById(R.id.Pass); 

       while(finish==false){ 
        try { 
         Thread.sleep(500); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        currentPlayer = game.getPlayer(); 

        if(currentPlayer.isPlayer()==false){ 

         //System.out.println("passCount:" +game.getPasscount()); 
         ai.decide(nextPlay, game.getPreviousPlayed(), currentPlayer, game.getPasscount()); 
         if(nextPlay.size()!=0){ 
          runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           if(nextPlay.size() ==1){ 
            play1Card(); 
           } 
           else if(nextPlay.size()==2){ 
            play2Card(); 
           } 
           else if(nextPlay.size()==3){ 
            play3Card(); 
           } 
           else if(nextPlay.size()==5){ 
            play5Card(); 
           } 
          } 
         } 
         else{ 
          game.addPassCount(); 
          game.nextTurn(); 
          runOnUiThread(new Runnable(){ 
           public void run(){ 
            changeArrow(); 
           } 
          }); 
         }  
        } 
        else if (currentPlayer.isPlayer()==true){ 
         runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           play.setClickable(true); 
           if(game.getPasscount()==3){ 
            pass.setClickable(false); 
           } 
           else{ 
            pass.setClickable(true); 
           } 
          } 
         }); 
        } 

      } 
      System.out.println("Game Ended"); 
      } 
    }; 

Bắt đầu và tham gia các chủ đề để các chủ đề chính:

 Thread myThread = new Thread(startGameLoop); 

    myThread.start(); 
    try { 
     myThread.join(); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    System.out.println("YAY"); 
} 

Để hiểu biết của tôi .join() làm cho sự chờ đợi thread hiện hành cho đến khi thread mới đã hoàn tất trước khi tiến hành.

Xin lỗi nếu đây là một câu hỏi ngu ngốc, tôi khá mới mẻ khi đọc.

+2

Chúng tôi cần thêm một chút ngữ cảnh. Trường hợp cuộc gọi này đến 'join()' xảy ra. Nhiều khả năng bạn đang làm điều này trên chuỗi giao diện người dùng, điều này sẽ giải thích lý do ứng dụng của bạn bị treo. –

+0

tham gia xảy ra trong onCreate() trong Lớp Hoạt động –

+0

Vì vậy, ứng dụng của bạn đang chờ một chuỗi chấm dứt trước khi kết thúc việc tạo Hoạt động. Đây có phải là * thực sự * những gì bạn muốn làm không? Nếu không, những gì * là * bạn đang cố gắng làm ở đây? –

Trả lời

5

Khi bạn gọi myThread.join() bên trong Activity.onCreate bạn chặn luồng giao diện người dùng chính. Tất nhiên có vẻ như ứng dụng của bạn dừng đáp ứng bởi vì chuỗi giao diện người dùng là chủ đề chịu trách nhiệm vẽ lại giao diện người dùng (duh). Tất cả các cuộc gọi của bạn runOnUiThread không bao giờ xảy ra bởi vì chuỗi giao diện người dùng của bạn đang bận chờ đợi trong vòng lặp trò chơi của bạn.

5

Thread.join làm cho luồng hiện tại chờ cho đến khi chuỗi bạn gọi nó kết thúc. Nó không gây ra các chủ đề bạn gọi nó trên để kết thúc. Vì vậy, nếu thread đó không bao giờ kết thúc (như bạn nói ở đầu), gọi tham gia sẽ làm cho nó treo mãi mãi.

Nếu bạn muốn thực sự kết thúc chuỗi, hãy hủy cuộc gọi đó. Nhưng điều đó đòi hỏi thread của bạn thỉnh thoảng gọi isCanceled() và thoát khỏi hàm chạy của nó nếu nó trả về true.

1

mythread.join() không đảm bảo rằng "huyền thoại" của bạn đã kết thúc.

Bạn cần đặt thông báo() trong vòng lặp trò chơi của mình.

... ...

System.out.println("Game Ended"); 
synchronized(mythread){ 
    mythread.notify(); 
} 

Về cơ bản, khi bạn thực hiện cuộc gọi chờ(), mã đợi trên màn hình của chủ đề, và một cuộc gọi đến thông báo() gây ra một sợi chờ đợi trên màn hình của đối tượng thức dậy. Ngoài ra, bạn có thể sử dụng notifyAll() để đánh thức tất cả các chuỗi đang chờ.

Hoặc, bạn có thể sử dụng phiên bản chờ của thời gian chờ(), trong đó chuỗi chờ đến khi được thông báo hoặc hết thời gian chờ.

+0

Bạn nên sử dụng 'Khóa' với' Điều kiện 'để đạt được điều này tốt hơn –

Các vấn đề liên quan