文章目录:
Demo3(实现Callable接口,重写call()方法)
写在前面
历时一个星期,终于整完了Java多线程高并发这个系列的相关内容,这是最后一篇关于多线程的文章了,打算回到最初学习多线程的起点:总结一下创建多线程的四种方式吧。
Demo1(继承Thread类,重写run()方法)
package com.szh.begin; /** * 实现多线程的第一种方式:继承Thread类,重写run()方法 */ public class Test01 { static class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } } public static void main(String[] args) { MyThread t1=new MyThread(); MyThread t2=new MyThread(); t1.setName("t1"); t2.setName("t2"); //start方法的作用是:启动一个分支线程,在JVW中开辟一个新的栈空间 //只要栈空间开辟出来,start方法就结束了,线程就启动成功了,启动成功的线程会自动调用run方法 //run方法在分支线程的栈底部,main方法在主线程的栈底部,run和main是平级的 t1.start(); t2.start(); //上面的代码也可以写成下面这种形式,只不过需要再来一个有参构造 // new MyThread("t1").start(); // new MyThread("t2").start(); } }
Demo2(实现Runnable接口,重写run()方法)
package com.szh.begin; /** * 实现多线程的第二种方式:实现Runnable接口,重写run()方法 * 传统写法 */ public class Test02 { static class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } } public static void main(String[] args) { new Thread(new MyRunnable(),"t1").start(); new Thread(new MyRunnable(),"t2").start(); } }
package com.szh.begin; /** * 实现多线程的第二种方式:实现Runnable接口,重写run()方法 * 匿名内部类写法 */ public class Test03 { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } }).start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } }).start(); } }
Demo3(实现Callable接口,重写call()方法)
package com.szh.begin; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 实现多线程的第三种方式:实现Callable接口,重写call()方法 * 使用FutureTask接收线程的执行结果 */ public class Test05 { static class MyCallable implements Callable<Object> { @Override public Object call() throws Exception { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } return "当前执行线程的id为:" + Thread.currentThread().getId(); } } public static void main(String[] args) throws ExecutionException, InterruptedException { //new一个未来任务类对象,参数传入一个Callable接口实现类对象 FutureTask<Object> task1=new FutureTask<>(new MyCallable()); FutureTask<Object> task2=new FutureTask<>(new MyCallable()); //创建两个线程对象,参数传入一个FutureTask对象,之后启动线程 new Thread(task1).start(); new Thread(task2).start(); //获取t1线程的执行结果 Object obj1=task1.get(); Object obj2=task2.get(); System.out.println(obj1); System.out.println(obj2); } }
Demo4(线程池 + Callable接口)
package com.szh.begin; import java.util.concurrent.*; /** * 实现多线程的第三种方式:实现Callable接口,重写call()方法 * 使用Future接收线程的执行结果 */ public class Test04 { static class MyCallable implements Callable<Object> { @Override public Object call() throws Exception { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } return "当前执行线程的id为:" + Thread.currentThread().getId(); } } public static void main(String[] args) throws ExecutionException, InterruptedException { //创建一个固定大小的线程池 ExecutorService service= Executors.newFixedThreadPool(2); //提交执行 Future<Object> future1=service.submit(new MyCallable()); Future<Object> future2=service.submit(new MyCallable()); //获取call()方法的返回值(即线程执行结果的返回值) Object obj1=future1.get(); Object obj2=future2.get(); //打印 System.out.println(obj1); System.out.println(obj2); //关闭线程池 service.shutdown(); } }