2015-12-17 27 views
6

Tôi có một bộ sưu tập (concurrentHashMap) và một phương pháp mà phải làm việc trong một thread riêng biệt và trở numOfApples:Cách trả về một giá trị từ biểu thức lambda?

public int getApples(String treeNum) { 
    int numOfApples = null; 
    Runnable task =() -> {concurrentHashMap.get(treeNum).getApples(); }; 
    new Thread(task).start() ; 
    return numOfApples; 
} 

Có thể vượt qua num táo từ biểu thức lambda (concurrentHashMap.get(treeNum).getApples()) vào biến numOfApples?

Trả lời

4

Sự cố không phải là trả về giá trị từ biểu thức lambda. Đó là về việc trả lại kết quả từ một tác vụ không đồng bộ.

Bạn sẽ không thể thực hiện điều đó dễ dàng bằng cách sử dụng Runnable. Thay vào đó, bạn nên sử dụng số Callable, trích dẫn Javadoc của mình:

Nhiệm vụ trả về kết quả và có thể ném ngoại lệ.

Ngoài ra, you definitely should not be creating unmanaged raw threads like that: new Thread(task).start();. You should use an ExecutorService and submit the Callable to it.

Xét đoạn mã sau:

public int getApples(String treeNum) { 
    Callable<Integer> task =() -> concurrentHashMap.get(treeNum).getApples(); 
    Future<Integer> future = Executors.newCachedThreadPool().submit(task); 
    return future.get(); 
} 

Nó tạo ra một Callable<Integer> giữ nhiệm vụ trả lại số táo. Nhiệm vụ này được gửi đến một ExecutorService (Tôi chỉ đơn giản là sử dụng một hồ bơi thread lưu trữ ở đây, bạn có thể muốn khác). Kết quả được chứa bên trong một cá thể Future<Integer>, có phương thức get() sẽ chặn, đợi kết quả và sau đó trả lại kết quả.

+2

Nhưng nếu OP nhấn mạnh vào nó, có thể tạo ['FutureTask'] (http://docs.oracle.com/javase/8/docs/api/?java/util/concurrent/FutureTask.html) bằng tay, chuyển nó tới một chuỗi mới được tạo thủ công, khởi động nó và gọi 'get' sau đó. Nguyên tắc cũng giống như trong câu trả lời của bạn. – Holger

+0

Tunaki, làm cách nào để kiểm tra phương thức đó thực hiện trong chuỗi riêng biệt? – May12

+0

Để kiểm tra xem phương thức có thực thi trong một luồng riêng biệt hay không, bạn có thể làm một cái gì đó như 'System.out.println (" Thread: "+ Thread.currentThread(). GetId());' trong phương thức 'getApples()' và trong 'Có thể gọi'. Các giá trị ID sẽ không giống nhau. –

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