定义线程类
1. 实现Runnable接口
public class Liftoff implements Runnable {
private int countDown = 10;
private static int taskCount = 0;
private final int id = taskCount++;
private String status() {
return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "), ";
}
public void run() {
while (countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}
2. 使用Thread类
public class BasicThreads {
public static void main(String[] args) {
Thread t1 = new Thread(new LiftOff());
t1.start();
Thread t2 = new Thread(new LiftOff());
t2.start();
System.out.println("Waiting for LiftOff");
}
}
- 缺点:继承Thread导致无法继承其他类,而实现Runnable接口的方式还能继承其他类
代码
public class SimpleThread extends Thread {
private int countDown = 5;
private static int threadCount = 0;
private SimpleThread() {
super(Integer.toString(++threadCount));
start();
}
public String toString() { return "#" + getName() + "(" + countDown + "), "; }
public void run() {
while (true) {
System.out.print(this);
if (--countDown == 9) return;
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new SimpleThread();
}
}
}
创建无限线程的线程池
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();
}
}
创建有限线程的线程池
public class FixedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdown();
}
}
创建单一线程
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdown();
}
}
- 相比Runnable接口,Callable接口可以从线程中返回一个值,这个值通过Future对象包装
class TaskWithResult implements Callable<String> {
private int id;
TaskWithResult(int id) { this.id = id; }
public String call() { return "result of TaskWithResult " + id; }
}
public class CallableDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(exec.submit(new TaskWithResult(i)));
}
for (Future<String> fs : results) {
try {
// get会阻塞程序
System.out.println(fs.get());
} catch (InterruptedException e) {
e.printStackTrace();
return;
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
exec.shutdown();
}
}
}
}
休眠
方式一
Thread.sleep(100);
方式二
TimeUnit.MILLISECONDS.sleep(100);
线程优先级
public class SimplePriorities implements Runnable {
private int countDown = 5;
private int priority;
private SimplePriorities(int priority) {
this.priority = priority;
}
public void run() {
// 设置优先级
Thread.currentThread().setPriority(priority);
while (true) {
for (int i = 1; i < 100000; i++) {
if (i % 1000 == 0) {
Thread.yield();
}
}
if (--countDown == 0) {
return;
}
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
}
exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
exec.shutdown();
}
}
后台线程
描述
- 当程序所有非后台线程中止时,后台线程会被杀死。
- 通常后台线程程序中不是不可或缺的部分。
- 后台线程创建的线程也是后台线程。
简单示例
public class SimpleDaemons implements Runnable {
public void run() {
try {
while (true) {
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] arms) throws Exception {
for (int i = 0; i < 10; i++) {
Thread daemon = new Thread(new SimpleDaemons());
// 设置此线程为后台线程
daemon.setDaemon(true);
daemon.start();
}
TimeUnit.MILLISECONDS.sleep(175);
}
}
// 通过实现ThreadFactory接口来实现创建线程时的预处理
class DaemonThreadFactory implements ThreadFactory {
public Thread newThread(@NotNull Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
public class DaemonThread implements Runnable {
public void run() {
try {
while (true) {
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (InterruptedException e) {
System.out.print("Interrupted");
}
}
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool(new DaemonThreadFactory());
for (int i = 0; i < 10; i++)
exec.execute(new DaemonThread());
TimeUnit.MILLISECONDS.sleep(500);
}
}
线程交互
- 有线程A和线程B,若在线程A中调用B.join(),则线程A会在此处挂起直至线程B结束。
- 有线程A和线程B,若在线程A中调用B.interrupt(),则线程B会中断并抛出异常。
异常处理器
class ExceptionThread implements Runnable {
public void run() {
Thread t = Thread.currentThread();
throw new RuntimeException();
}
}
// 实现接口Thread.UncaughtExceptionHandler作为异常处理器
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ViAritcPtiln'e");
}
}
class HandlerThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
// 每个线程都绑定一个异常处理器
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
// 设置默认线程处理器
// Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread());
}
}