Hãy nói rằng tôi có một phương pháp doWork()
. Làm thế nào để tôi gọi nó từ một chủ đề riêng biệt (không phải chủ đề chính).
Hãy nói rằng tôi có một phương pháp doWork()
. Làm thế nào để tôi gọi nó từ một chủ đề riêng biệt (không phải chủ đề chính).
Câu trả lời:
Tạo một lớp thực hiện Runnable
giao diện. Đặt mã bạn muốn chạy trong run()
phương thức - đó là phương pháp mà bạn phải viết để tuân thủ Runnable
giao diện. Trong luồng "chính" của bạn, tạo một Thread
lớp mới , truyền cho hàm tạo một thể hiện của bạn Runnable
, sau đó gọi start()
nó. start
yêu cầu JVM thực hiện phép thuật để tạo một luồng mới và sau đó gọi run
phương thức của bạn trong luồng mới đó.
public class MyRunnable implements Runnable {
private int var;
public MyRunnable(int var) {
this.var = var;
}
public void run() {
// code in the other thread, can reference "var" variable
}
}
public class MainThreadClass {
public static void main(String args[]) {
MyRunnable myRunnable = new MyRunnable(10);
Thread t = new Thread(myRunnable)
t.start();
}
}
Hãy xem hướng dẫn đồng thời của Java để bắt đầu.
Nếu phương thức của bạn sẽ được gọi thường xuyên, thì có thể không đáng để tạo một luồng mới mỗi lần, vì đây là một hoạt động tốn kém. Có lẽ tốt nhất là sử dụng một nhóm chủ đề nào đó. Hãy nhìn vào Future
, Callable
, Executor
lớp trong java.util.concurrent
gói.
run()
phương pháp có không có thông số, vì vậy bạn không thể vượt qua một biến đó. Tôi khuyên bạn nên chuyển nó trong hàm tạo - Tôi sẽ chỉnh sửa câu trả lời của tôi để hiển thị điều đó.
new Thread() { public void run() {myMethod();}}.start();
đường đi, đó có phải là ngắn nhất?
Runnable
- của tôi là một lớp mở rộng Runnable
. Và bởi vì tôi đã thực hiện rằng tôi có hàm tạo riêng của mình chuyển trạng thái vào đối tượng được khởi tạo.
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
hoặc là
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
hoặc là
new Thread(() -> {
// code goes here.
}).start();
hoặc là
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
hoặc là
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()
?
Trong Java 8, bạn có thể làm điều này với một dòng mã.
Nếu phương thức của bạn không lấy bất kỳ tham số nào, bạn có thể sử dụng tham chiếu phương thức:
new Thread(MyClass::doWork).start();
Mặt khác, bạn có thể gọi phương thức trong biểu thức lambda:
new Thread(() -> doWork(someParam)).start();
->
có nghĩa là gì?
Celery task queue
cho những thứ không đồng bộ
Trước đây, tôi đã viết một lớp tiện ích đơn giản sử dụng dịch vụ thực thi JDK5 và thực thi các quy trình cụ thể trong nền. Do doWork () thường có giá trị trả về void, nên bạn có thể muốn sử dụng lớp tiện ích này để thực thi nó trong nền.
Xem bài viết này , nơi tôi đã ghi lại tiện ích này.
Để đạt được điều này với RxJava 2.x, bạn có thể sử dụng:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
Các subscribeOn()
quy định cụ thể phương pháp mà lên lịch để chạy các hành động trên - RxJava có một số schedulers được xác định trước, bao gồm Schedulers.io()
trong đó có một hồ bơi thread dành cho I / O hoạt động, và Schedulers.computation()
đó là dành cho CPU hoạt động chuyên sâu.
Nếu bạn đang sử dụng ít nhất Java 8, bạn có thể sử dụng phương thức runAsync
từ lớp CompleteableFuture
CompletableFuture.runAsync(() -> {...});
Nếu bạn cần trả lại kết quả sử dụng supplyAsync
thay thế
CompletableFuture.supplyAsync(() -> 1);