一、定义任务
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();
}
}