2013-04-07 30 views
8

Tôi đang viết ứng dụng nhỏ và bây giờ tôi đã phát hiện ra một vấn đề. Tôi cần phải gọi một (sau đó có thể là hai) phương pháp (phương pháp này tải một cái gì đó và trả về kết quả) mà không bị tụt hậu trong cửa sổ ứng dụng.Cách dễ dàng để gọi phương thức trong chủ đề mới

Tôi đã tìm thấy các lớp học như Executor hoặc Callable, nhưng tôi không hiểu cách làm việc với những lớp đó.

Bạn có thể vui lòng đăng bất kỳ giải pháp nào giúp tôi không?

Cảm ơn mọi lời khuyên.

Chỉnh sửa: Phương pháp PHẢI trả lại kết quả. Kết quả này phụ thuộc vào parametrs. Một cái gì đó như thế này:

public static HtmlPage getPage(String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException { 
     return webClient.getPage(page); 
} 

Phương pháp này hoạt động khoảng 8-10 giây. Sau khi thực thi phương thức này, luồng có thể được dừng lại. Nhưng tôi cần phải gọi các phương pháp sau mỗi 2 phút.

Edit: tôi sửa mã với điều này:

public static HtmlPage getPage(final String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException { 
    Thread thread = new Thread() { 
     public void run() { 
      try { 
       loadedPage = webClient.getPage(page); 
      } catch (FailingHttpStatusCodeException | IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 
    thread.start(); 
    try { 
     return loadedPage; 
    } catch (Exception e) { 
     return null; 
    } 

} 

Với mã này, tôi nhận được lỗi một lần nữa (thậm chí nếu tôi đặt return null ra khỏi bắt khối).

+1

[ 'Executor'] (http://docs.oracle. com/javase/7/docs/api/java/util/concurrent/Executor.html) và ['ExecutorService'] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent /ExecutorService.html) có các ví dụ trong javadoc. Và [một chủ đề] (http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html) trên chuỗi * concurrency * trong hướng dẫn chính thức. Đó là nơi tôi bắt đầu. Bạn nên hỏi một câu hỏi mới nếu bạn không hiểu điều gì đó * cụ thể * trong những tài liệu đó, hoặc nếu bạn đang mắc kẹt khi sử dụng thông tin trong đó. – millimoose

+0

Tôi thấy các ví dụ, nụ tôi không thể đạt được những gì tôi muốn. – Sk1X1

+1

Tôi * nghĩ * những gì bạn đang tìm kiếm ['ExecutorService.submit()'] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit (java.util.concurrent.Callable)) với một 'Callable ', vì vậy hãy tập trung vào tài liệu cho các lớp và các phương thức liên quan. 'submit()' sẽ trả về một 'Tương lai ' mà sẽ cho phép bạn làm điều gì đó (như cập nhật giao diện người dùng) khi kết quả có sẵn. – millimoose

Trả lời

22

Thứ nhất, tôi khuyên bạn nên xem Java Thread Documentation.

Với chủ đề, bạn có thể chuyển vào loại giao diện được gọi là Runnable. Các tài liệu có thể được tìm thấy here. Một runnable là một đối tượng có phương thức run. Khi bạn bắt đầu một chuỗi, nó sẽ gọi bất kỳ mã nào trong phương thức run của đối tượng runnable này. Ví dụ:

Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
       // Insert some method call here. 
     } 
}); 

Bây giờ, điều này có nghĩa là khi bạn gọi t.start(), nó sẽ chạy bất cứ mã bạn cần nó để không tụt hậu các chủ đề chính. Đây được gọi là cuộc gọi phương thức Asynchronous, có nghĩa là cuộc gọi này chạy song song với bất kỳ chủ đề nào khác mà bạn đã mở, như chuỗi main của bạn. :)

+0

Tôi thử một cái gì đó như thế này, nhưng nó không hoạt động (thông tin thêm trong câu trả lời tiếp theo) – Sk1X1

+0

làm thế nào để vượt qua đối số cho phương pháp gọi –

20

Kể từ Java 8 bạn có thể sử dụng hình thức ngắn hơn:

new Thread(() -> { 
    // Insert some method call here. 
}).start(); 

Cập nhật: Ngoài ra, bạn có thể sử dụng phương pháp tham khảo:

class Example { 

    public static void main(String[] args){ 
     new Thread(Example::someMethod).start(); 
    } 

    public static void someMethod(){ 
     // Insert some code here 
    } 

} 

Bạn có thể sử dụng nó khi bạn danh sách đối số giống như trong yêu cầu @FunctionalInterface, ví dụ: Runnable hoặc Callable.

Xem thêm: Platform.runLater and Task in JavaFX, Method References.

1

Trong Java 8 nếu không có thông số cần thiết bạn có thể sử dụng:

new Thread(MyClass::doWork).start(); 

Hoặc trong trường hợp các thông số:

new Thread(() -> doWork(someParam)) 
+0

Đó là tương đối. Các tham số chỉ ẩn và nó phụ thuộc vào các tham số đầu vào của giao diện. Khi bạn viết 'Thread mới (MyClass :: doWork) .start();' bạn cũng có thể viết 'new Thread (() -> doWork())' cho Runabble không có tham số đầu vào. Nhưng nếu bạn yêu cầu đầu vào từ một biến mà nó ở bên ngoài việc đóng cửa, hơn có, bạn có thể làm theo cách thứ hai. –

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