线程创建方式
1 线程有3种创建方式:
- 继承Thread类
- 实现Runnable接口
- Callable接口与Future配合使用
2 实现
2.1 继承Thread类
public class MyThread extends Thread { public MyThread() { } public void run() { for(int i=0;i<10;i++) { System.out.println(Thread.currentThread()+":"+i); } } public static void main(String[] args) { MyThread mThread1=new MyThread(); MyThread mThread2=new MyThread(); MyThread myThread3=new MyThread(); mThread1.start(); mThread2.start(); myThread3.start(); } }
2.2 实现Runnable接口
案例:龟兔赛跑,100米的距离让乌龟最终赢得比赛

public class Race implements Runnable { private static String winner; @Override public void run() { for (int i = 0; i <= 100; i++) { // 兔子线程每10步休息一次 if (Thread.currentThread().getName().equals("兔子") && i % 10 == 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } boolean isWinner = isWinner(i, Thread.currentThread().getName()); if (isWinner) { System.out.println("胜利者是" + winner); } } } private boolean isWinner(int i, String name) { if (winner != null) { return false; } if (i == 100) { winner = name; return true; } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race, "兔子").start(); new Thread(race, "乌龟").start(); } }

2.3 实现Callable接口
public class DownloadCall implements Callable<Boolean> { @Override public Boolean call() throws Exception { System.out.println("线程执行成功," + Thread.currentThread().getName()); return null; } public static void main(String[] args) throws ExecutionException, InterruptedException { DownloadCall call1 = new DownloadCall(); DownloadCall call2 = new DownloadCall(); DownloadCall call3 = new DownloadCall(); // 创建执行服务 ExecutorService service = Executors.newFixedThreadPool(3); // 执行提交 Future<Boolean> r1 = service.submit(call1); Future<Boolean> r2 = service.submit(call2); Future<Boolean> r3 = service.submit(call3); // 获取结果 Boolean rs1 = r1.get(); Boolean rs2 = r2.get(); Boolean rs3 = r3.get(); // 关闭服务 service.shutdown(); } }
3 对比
3.1 Thread与Runnable比较
- 继承Thread优缺点
- 优点:编写简单;
- 缺点:Java是单继承,若继承了Thread则不能在继承别的类;
- 实现Runnable优缺点
- 优点:避免了单继承的局限性,方便同一个对象被多个线程使用;
- 缺点:没有返回值,异常不能抛出,只能自身捕获处理;
3.2 Runnable与Callable比较
相同点:
- 都是接口
- 都采用Thread.start()启动线程
不同点:
- Runnable没有返回值;Callable可以返回执行结果,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果
- Callable接口的call()方法允许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛注:
- Callalble接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

浙公网安备 33010602011771号