java多线程-从继承Thread类和实现Runnable接口到java多线程实现
java实现多线程有三种方式
1、实现Runnable接口
2、继承Thread类
3、使用Callable接口的call方法建立FutrueTask对象
1.实现Runnable接口
1 class MyThread implements Runnable{ // 实现Runnable接口,作为线程的实现类 2 private String name ; // 表示线程的名称 3 public MyThread(String name){ 4 this.name = name ; // 通过构造方法配置name属性 5 } 6 public void run(){ // 覆写run()方法,作为线程 的操作主体 7 for(int i=0;i<10;i++){ 8 System.out.println(name + "运行,i = " + i) ; 9 } 10 } 11 }; 12 public class RunnableDemo01{ 13 public static void main(String args[]){ 14 MyThread mt1 = new MyThread("线程A ") ; // 实例化对象 15 MyThread mt2 = new MyThread("线程B ") ; // 实例化对象 16 Thread t1 = new Thread(mt1) ; // 实例化Thread类对象 17 Thread t2 = new Thread(mt2) ; // 实例化Thread类对象 18 t1.start() ; // 启动多线程 19 t2.start() ; // 启动多线程 20 } 21 };
通过实现Runnable接口覆写run()方法
2.继承Thread类
1 class MyThread extends Thread{ // 继承Thread类,作为线程的实现类 2 private String name ; // 表示线程的名称 3 public MyThread(String name){ 4 this.name = name ; // 通过构造方法配置name属性 5 } 6 public void run(){ // 覆写run()方法,作为线程 的操作主体 7 for(int i=0;i<10;i++){ 8 System.out.println(name + "运行,i = " + i) ; 9 } 10 } 11 }; 12 public class ThreadDemo01{ 13 public static void main(String args[]){ 14 MyThread mt1 = new MyThread("线程A ") ; // 实例化对象 15 MyThread mt2 = new MyThread("线程B ") ; // 实例化对象 16 mt1.run() ; // 调用线程主体 17 mt2.run() ; // 调用线程主体 18 } 19 };
通过继承Thread类来重写Thread中的run()方法
3.实现Callable接口
1 public static class CallerTask implements Callable<String>{ 2 3 @Override 4 public String Call() throws Exception { 5 return "hello"; 6 } 7 8 } 9 10 public static void main(String[] args) throws InterruptedException { 11 //创建异步任务 12 FutureTask<String> futureTask = new FutureTask<>(new CallerTask()); 13 //启动线程 14 new Thread(futureTask).start(); 15 try{ 16 //等待任务执行完毕,并返回结果 17 String result = futureTask.get(); 18 System.out.println(result); 19 } catch (ExecutionException e) { 20 e.printStackTrance(); 21 } 22 }
CallerTask类实现了Callable接口中的call()方法。在main函数中创建了一个FutrueTask对象(构造函数为CallTask的实例),然后使用创建的FutrueTask对象作为任务创建了一个线程并且启动它,最后通过futrueTask.get()等待任务执行完毕并返回结果。
4.Thread类与Runnable接口的联系
Thread类也是Runnable接口的子类
4.1 区别
使用Thread类在操作多线程的时候无法达到资源共享的目的,而使用Runnable接口实现的多线程操作可以实现资源共享
使用Thread类的好处是方便传参,可以在子类中添加成员变量,通过set方法设置参数或者通过构造函数进行传递。
4.2 结论
实现Runnable接口比继承Thread类有如下明显的优点
- 适合多个相同程序代码的线程去处理同一个资源
- 可以避免单继承局限所带来的影响
- 增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的
5.线程状态的理解
多线程在操作中是用固定操作状态的
- 创建状态:准备好了一个多线程的对象:Thread t = new Thread()
- 就绪状态:调用了start()方法,等待CPU进行调度
- 运行状态:执行了run()方法
- 阻塞状态:暂时停止执行,可能将资源交给其他线程使用
- 终止状态:线程执行完毕,不再使用