一、定義任務
public class LiftOff implements Runnable {
protected int countDown = 10;
private static int taskCount = 0;
/**
* 標識符ID可以用來區分任務的多個實例,final表示一旦被初始化之後就不希望被修改
*/
private final int id = taskCount++;
public LiftOff() {
}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "). ";
}
public void run() {
while (countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}
public class MainThread {
public static void main(String[] args) {
LiftOff launch = new LiftOff();
launch.run();
}
}
二、Thread類
public class MoreBasicThreads {
public static void main(String[] args) {
for (int i=0; i<5; i++) {
new Thread(new LiftOff()).start();
}
System.out.println("Waiting for LiftOff");
}
}
三、使用Executor
java.util.concurrent包中的執行器(Executor)管理Thread對象,從而簡化了併發編程。
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i =0; i < 5; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
shutdown()方法的調用可以防止新任務被提交給這個Executor.
CachedThreadPool:爲每個任務都創建一個線程。
FixedThreadPool:使用有限的線程執行多個任務。
SingleThreadExecutor:使用一個線程執行多個任務。
四、從任務中產生返回值
Runnable是執行工作的獨立任務,但是它不返回任何值。如果希望在任務完成時能夠返回一個值,那麼可以實現Callable接口而不是Runnable接口。並且必須使用ExecutorService.submit()方法調用它:
import java.util.concurrent.Callable;
public class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
this.id = id;
}
@Override
public String call() {
return "result of TaskWithResult " + id;
}
}
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<Future<String>>();
for (int i = 0; i < 10; i++) {
results.add(exec.submit(new TaskWithResult(i)));
}
for (Future<String> fs : results) {
try {
System.out.println(fs.get());
} catch (InterruptedException e) {
System.out.println(e);
return;
} catch (ExecutionException e) {
System.out.println(e);
} finally {
exec.shutdown();
}
}
}
}
submit方法會產生Future對象,它用callable返回結果的特定類型進行了參數化。用isDone()方法來查詢Future是否已經完成。當任務完成時,它具有一個結果,你可以調用get()方法來獲取該結果。當不用isDone進行檢查就直接調用get(),在這種情況下,get()講阻塞,直到結果準備就緒。
五、休眠
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class SleepingTask extends LiftOff {
public void run() {
try {
while (countDown-- > 0) {
System.out.print(status());
TimeUnit.MICROSECONDS.sleep(10000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
exec.execute(new SleepingTask());
}
exec.shutdown();
}
}
六、優先級
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimplePriorites implements Runnable {
private int countDown = 5;
private volatile double d;
private int priority;
public SimplePriorites(int priority) {
this.priority = priority;
}
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
@Override
public void run() {
Thread.currentThread().setPriority(priority);
while (true) {
for (int i = 1; i < 10000; i++) {
d += (Math.PI + Math.E) / (double) i;
if (i % 2 == 0) {
Thread.yield();
}
System.out.println(this);
if (--countDown ==0){
return;
}
}
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
exec.execute(new SimplePriorites(Thread.MIN_PRIORITY));
}
exec.execute(new SimplePriorites(Thread.MAX_PRIORITY));
exec.shutdown();
}
}