2012-03-21 35 views
7

Tôi có một ứng dụng mà khi có thống kê "trò chơi", nó bắt đầu một vài chủ đề khác nhau. Tôi bắt đầu đề như vậy:Thực hành tốt cho đa luồng

Thread thread = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     //... 
    } 
}); 

thread.setName("killMeAtEnd"); 
thread.start(); 

Sau khi trận đấu kết thúc tôi có một phương pháp xử lý() bên trong trò chơi mà sắp xếp thông qua tất cả các chủ đề chạy và kết thúc tất cả các chủ đề có tên "killMeAtEnd" . Câu hỏi của tôi là, thực hành tốt này? Ý định của tôi là giữ cho ứng dụng của tôi chạy nhanh và lộn xộn miễn phí, theo kinh nghiệm của tôi Chỉ còn lại "treo" có xu hướng làm chậm điện thoại cho đến khi ứng dụng bị chấm dứt. Có cách nào tốt hơn để làm điều này? Điều này thậm chí có đáng làm phiền không?

EDIT:

Đây là tôi dispose() nếu có ai đã quan tâm. Mã này nằm trong lớp Game.

public void dispose() 
{ 
    Thread threads[] = (Thread[])Thread.getAllStackTraces().keySet().toArray(); 
    for(int x=0;x<threads.length;x++) 
    { 
     Thread thread = threads[x]; 
     if(thread.getName().equalsIgnoreCase(KILL)) 
     { 
      try 
      { 
       thread.interrupt(); 
      }catch(Exception e){Log.e(Viewer.GAME,Log.getStackTraceString(e));} 
      thread = null; 
     } 
    } 
} 

public static final String KILL = "endOnDispose"; 
+0

Bắt stacktraces là khá tốn kém vì vậy nó sẽ có hiệu quả hơn nếu bạn sẽ lưu 'chủ đề []' trong khi bạn tạo ra các chủ đề và làm cho nó 'vứt bỏ (Thread [] chủ đề)'. Có chủ đề nào khác tiếp tục chạy khi trò chơi của bạn kết thúc hoặc là để ngăn bạn giết chết chuỗi giao diện người dùng không? – zapl

+0

Khi "trò chơi" kết thúc Hoạt động không kết thúc, nó sẽ chuyển sang mục khác. – John

Trả lời

4

Bạn có ý tưởng đúng, nhưng có một số khu vực để cải thiện:

  1. Thay vì truy vấn hệ thống cho tất cả các chủ đề hoạt động, chỉ cần thêm chủ đề của bạn vào một danh sách bất cứ khi nào bạn tạo chúng. Sau đó, bạn có thể chấm dứt tất cả các chủ đề mà bạn đã tạo hoặc chờ hoàn thành (tham gia).
  2. Ngắt chỉ ngắt một luồng trong trạng thái chặn, vì vậy bạn cần có thêm cờ mà chuỗi sẽ kiểm tra định kỳ (tức là sau mỗi "chu kỳ công việc").
  3. Ghi ngoại lệ ngắt trong chuỗi của bạn và xử lý nó (ví dụ: thoát ra một cách duyên dáng).
+0

+1 Cảm ơn! Tôi đã kết thúc việc đưa tất cả các chuỗi của mình vào một danh sách và sau đó giết chúng sau khi trò chơi được thực hiện. – John

3

Đây không phải là thiết một giải pháp xấu, nhưng có một vài vấn đề:

  • Nếu chủ đề của bạn là đề người lao động của các loại có thể xử lý một nhiệm vụ để hoàn thành, có có thể là một thiết kế tốt hơn trong đó chủ đề kết thúc chính nó. Nói cách khác, có thể có một dòng chảy thực hiện tốt hơn, mà không yêu cầu bị giết ở cuối.

  • Khi bạn nói "sắp xếp tất cả các chủ đề đang chạy ...", tôi tưởng tượng bạn đang xem TẤT CẢ các chủ đề đang chạy trong JVM? như trong một cái gì đó dọc theo dòng this SO question? Nếu đó là trường hợp, tại sao bạn không chỉ giữ một tham chiếu đến tất cả các chủ đề mà trò chơi của bạn sở hữu thay vào đó, và sau đó cụ thể giết chết chúng? Trái với việc chỉ tìm kiếm "killMeAtEnd"; Tôi không thể nghĩ chiến lược của bạn có thể sai như thế nào, nhưng nó có vẻ sạch hơn một chút để theo dõi các chủ đề của bạn.

Chắc chắn là thực hành tốt để giữ cho luồng sạch. Nếu chủ đề của bạn đang làm điều gì đó ít cụ thể hơn theo định hướng nhiệm vụ (ví dụ: chờ mạng io hoặc thứ gì đó), thì đề xuất đầu tiên của tôi có phần không liên quan. Tôi sẽ chỉ đề nghị rất cẩn thận về thiết kế của cách bạn giữ cho các chủ đề của bạn sạch sẽ, bởi vì các lỗi có chủ đề có thể là một nỗi đau lớn.

+0

+1 cảm ơn sự trợ giúp! – John

0

Lớp ExecutorService đã tồn tại để xử lý loại sự cố này.

Làm cho tất cả các nhiệm vụ chủ đề của bạn cho ExecutorService.

Khi trò chơi kết thúc, tắt ExecutorService bằng cách tắt shutdownNow. Điều này sẽ làm gián đoạn ngắt tất cả các luồng trong ExecutorService.Sau đó bạn có thể tạo một ExecutorService mới khi bạn bắt đầu một trò chơi mới.

Nếu số lượng chủ đề được sửa, bạn có thể sử dụng Executors.newFixedThreadPool() để tạo ExecutorService.

Nếu số lượng chủ đề là biến, bạn có thể sử dụng Executors.newCachedThreadPool để tạo ExecutorService.

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