Java中线程创建的方式
1 继承Thread
格式:
1 2 3 4 5 6 7 8 | class 类名 extends Thread{ //重写run()方法 public void run(){ //这里的代码就是一条新的执行路径。 //这个执行路径的触发方式不是调用run方法,而是通过thread对象的start来启动任务 } } |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Demo { public static void main(String[] args) { MyThread m = new MyThread(); m.start(); for (int i = 0; i < 10; i++) { System.out.println("汗滴禾下土" + i); } } } class MyThread extends Thread{ /** * run方法就是线程要执行的任务方法 */ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("锄禾日当午" + i); } } } |
运行结果:抢占式调度,运行结果不唯一。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 锄禾日当午0 汗滴禾下土0 锄禾日当午1 锄禾日当午2 汗滴禾下土1 锄禾日当午3 汗滴禾下土2 锄禾日当午4 汗滴禾下土3 锄禾日当午5 汗滴禾下土4 锄禾日当午6 汗滴禾下土5 锄禾日当午7 汗滴禾下土6 锄禾日当午8 汗滴禾下土7 锄禾日当午9 汗滴禾下土8 汗滴禾下土9 |
2 实现Runnable
格式:
1 2 3 4 5 6 | class 类名 implements Runnable{ public void run(){ //线程要执行的任务 } } |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class Demo2 { public static void main(String[] args) { //实现Runnable //1. 创建一个任务对象 MyRunnable m = new MyRunnable(); //2. 创建一个线程,并为其分配一个任务 Thread t = new Thread(m); //3. 执行这个线程 t.start(); for (int i = 0; i < 10; i++) { System.out.println("疑是地上霜" + i); } } } class MyRunnable implements Runnable{ @Override public void run() { //线程的任务 for (int i = 0; i < 10; i++) { System.out.println("床前明月光" + i); } } } |
运行结果:抢占式调度,运行结果不唯一。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 疑是地上霜0 床前明月光0 疑是地上霜1 床前明月光1 疑是地上霜2 床前明月光2 床前明月光3 床前明月光4 床前明月光5 床前明月光6 床前明月光7 疑是地上霜3 床前明月光8 疑是地上霜4 床前明月光9 疑是地上霜5 疑是地上霜6 疑是地上霜7 疑是地上霜8 疑是地上霜9 |
实现Runnable 与 继承Thread相比有如下优势:
- 通过创建任务,然后给线程分配的方式来实现多线程,更适合多个线程同时执行相同任务的情况。
- 可以避免单继承带来的局限性。
- 任务与线程本身是分离的,提高了程序的健壮性。
- 线程池技术,接收Runnable类型的任务,不接收Thread类型的线程。
3 实现Callable
格式:
1 2 3 4 5 6 7 | class 类名 implements Callable<T>{ T call() throws Exception{ //线程执行的任务 return T; } } |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class Demo11 { public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<Integer> c = new MyCallable(); FutureTask<Integer> task = new FutureTask<Integer>(c); new Thread(task).start(); Integer j = task.get(); System.out.println("返回值:" + j); for (int i = 0; i < 10; i++) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i); } } static class MyCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { for (int i = 0; i < 10; i++) { Thread.sleep(100); System.out.println(i); } return 100; } } } |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 0 1 2 3 4 5 6 7 8 9 返回值:100 0 1 2 3 4 5 6 7 8 9 |
4 线程池
以定长线程池为例显示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class Demo{ public static void main(String[] args){ ExecutorService service = Executors.newFixedThreadPool(2); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "锄禾日当午"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "锄禾日当午"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "锄禾日当午"); } }); } } |
运行结果:
1 2 3 | pool-1-thread-1锄禾日当午 pool-1-thread-2锄禾日当午 pool-1-thread-1锄禾日当午 |