doWork()
สมมติว่าผมมีวิธีการ ฉันจะเรียกมันจากเธรดแยกต่างหากได้อย่างไร (ไม่ใช่เธรดหลัก)
doWork()
สมมติว่าผมมีวิธีการ ฉันจะเรียกมันจากเธรดแยกต่างหากได้อย่างไร (ไม่ใช่เธรดหลัก)
คำตอบ:
สร้างคลาสที่ใช้Runnable
อินเทอร์เฟซ ใส่รหัสที่คุณต้องการเรียกใช้ในrun()
วิธีการซึ่งเป็นวิธีการที่คุณต้องเขียนเพื่อให้สอดคล้องกับRunnable
อินเทอร์เฟซ ในเธรด "หลัก" ของคุณสร้างThread
คลาสใหม่ส่งตัวสร้างอินสแตนซ์ของคุณRunnable
จากนั้นเรียกstart()
ใช้ start
บอกให้ JVM ใช้เวทมนตร์เพื่อสร้างเธรดใหม่จากนั้นเรียกrun
ใช้เมธอดของคุณในเธรดใหม่นั้น
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();
}
}
ดูบทแนะนำการทำงานพร้อมกันของ Javaเพื่อเริ่มต้น
หากมีการเรียกวิธีการของคุณบ่อยๆการสร้างเธรดใหม่ในแต่ละครั้งอาจไม่คุ้มค่าเนื่องจากเป็นการดำเนินการที่มีราคาแพง อาจเป็นการดีที่สุดที่จะใช้กลุ่มเธรดบางประเภท มีลักษณะที่Future
, Callable
, Executor
เรียนในjava.util.concurrent
แพคเกจ
run()
วิธีจะไม่มีพารามิเตอร์ดังนั้นคุณจึงไม่สามารถส่งผ่านตัวแปรมี ฉันขอแนะนำให้คุณส่งผ่านในตัวสร้าง - ฉันจะแก้ไขคำตอบเพื่อแสดงให้เห็นว่า
new Thread() { public void run() {myMethod();}}.start();
วิธีนั้นสั้นที่สุด?
Runnable
- Runnable
ฉันเป็นคลาสที่ขยาย และเนื่องจากฉันได้ทำไปแล้วว่าฉันมีตัวสร้างของตัวเองซึ่งส่งผ่านสถานะไปยังวัตถุที่สร้างอินสแตนซ์
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
หรือ
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
หรือ
new Thread(() -> {
// code goes here.
}).start();
หรือ
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
หรือ
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()
?
ใน Java 8 คุณสามารถทำได้ด้วยโค้ดหนึ่งบรรทัด
หากวิธีการของคุณไม่ใช้พารามิเตอร์ใด ๆ คุณสามารถใช้การอ้างอิงวิธีการ:
new Thread(MyClass::doWork).start();
มิฉะนั้นคุณสามารถเรียกใช้เมธอดในนิพจน์แลมบ์ดา:
new Thread(() -> doWork(someParam)).start();
->
หมายความว่าอย่างไร
Celery task queue
สำหรับสิ่งที่ไม่ตรงกัน
อีกตัวเลือกหนึ่งที่เร็วกว่าในการเรียกสิ่งต่างๆ (เช่น DialogBoxes และ MessageBoxes และการสร้างเธรดแยกต่างหากสำหรับวิธีการที่ไม่ปลอดภัยของเธรด) คือการใช้ Lamba Expression
new Thread(() -> {
"code here"
}).start();
เมื่อไม่นานมานี้ฉันได้เขียนคลาสยูทิลิตี้ง่ายๆที่ใช้บริการตัวดำเนินการ JDK5 และดำเนินการกระบวนการเฉพาะในพื้นหลัง เนื่องจากโดยทั่วไปแล้ว doWork () จะมีค่าส่งคืนเป็นโมฆะคุณอาจต้องการใช้คลาสยูทิลิตี้นี้เพื่อดำเนินการในพื้นหลัง
ดูบทความนี้ที่ฉันได้บันทึกยูทิลิตี้นี้
เพื่อให้บรรลุสิ่งนี้ด้วย RxJava 2.x คุณสามารถใช้:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
subscribeOn()
วิธีการระบุที่ตารางเวลาที่จะเรียกการกระทำบน - RxJava มีกำหนดการที่กำหนดไว้ล่วงหน้าหลายแห่งรวมถึงSchedulers.io()
ที่มีสระว่ายน้ำด้ายไว้สำหรับการดำเนินการ I / O และSchedulers.computation()
ซึ่งมีวัตถุประสงค์สำหรับการดำเนินการอย่างเข้มข้น CPU
หากคุณใช้ Java 8 เป็นอย่างน้อยคุณสามารถใช้เมธอดrunAsync
จากคลาสCompletableFuture
CompletableFuture.runAsync(() -> {...});
หากคุณต้องการส่งคืนผลลัพธ์ให้ใช้supplyAsync
แทน
CompletableFuture.supplyAsync(() -> 1);