创建新执行线程有三种方法。

第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。

例如,计算大于某一规定值的质数的线程可以写成:

class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}

然后,下列代码会创建并启动一个线程:

     PrimeThread p = new PrimeThread(143);p.start();
1,继承Thread
定义类继承Thread
重写run方法
把新线程要做的事写到run方法中
创建线程对象
开启新线程,内部会自动执行run方法

具体的多线程实现代码如下:

package com.yy.thread;public class Demo2_Thread {/*** 创建新执行线程有两种方法。* 一种方法是* ①将类声明为 Thread 的子类。* ②该子类应重写 Thread 类的 run 方法。* ③接下来可以分配并启动该子类的实例。* */public static void main(String[] args) {//开启一条线程Mythread mt = new Mythread();           //4,创建线程(Thread类)的子类对象mt.start();                             //5,开启线程,需要一定的时间,所以说,JVM会先执行for循环语句,也就是,会先输出bb,之后再输出aaaaaaa;然后再相互交替输出//public void start() : 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
//      mt.run();                               //如果这样调用,只是调用了run方法,执行run方法里面的for循环,线程还是主线程这一个线程,不会出现交替的多线程形式//主线程for (int i = 0; i < 100; i++) {         //为了便于观察多线程的执行,在主方法里面进行for循环System.out.println("bb");           //这个for循环就是主线程的,两条线程开启多线程便于观察}//两条线程相互交替进行,即多线程实现}}
class Mythread extends Thread{                  //1,继承Threadpublic void run(){                          //2,重写run方法for (int i = 0; i < 100; i++) {         //3,将要执行的代码写到run方法中System.out.println("aaaaaaa");  }}
}

创建线程的第二种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。

然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

采用这种风格的同一个例子如下所示:

     class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}

然后,下列代码会创建并启动一个线程:
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

     PrimeRun p = new PrimeRun(143);new Thread(p).start();
2,实现Runnable
定义类实现Runnable接口
实现run方法
把新线程要做的事先到run方法中
创建自定义的Runnable子类对象
创建Tread对象,传入Runnable
调用start()开启新线程,内部会自动调用Runnable的run()方法

具体的多线程实现代码如下:

package com.yy.thread;public class Demo3_Thread {/*** 创建线程的另一种方法是* ①声明实现 Runnable 接口的类。* ②该类然后实现 run 方法。* ③然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。* * Runnable里面只有一个run()方法,实现Runnable只需要重写run()方法即可* * * 实现Runnable的原理* 查看源码:*      1,看Thread类的构造函数,传递了Runnable接口的引用*      2,通过init()方法找到传递的target给成员变量的target赋值*      3,查看run方法,发现run方法中有判断,如果target不为null就会调用Runnable接口子类对象的run方法* */public static void main(String[] args) {MyRunnable wsq = new MyRunnable();                  //4,创建Runnable的子类对象
//      Runnable target = wsq;                              //父类引用指向子类对象,new MyRunnable()这个是子类对象也就是wsq  Thread yy = new Thread(wsq);                        //5,将其当作参数传递给Thread的构造函数; wsq代表Runnable的子类对象yy.start();                                         //6,开启线程; Thread里面才有start()方法//      new Thread(wsq).start();                            //这种方法与上面的两行代码实现的做用一样for (int i = 0; i < 100; i++) {System.out.println("你,陪我步入蝉夏,越过城市喧嚣,歌声还在游走,你榴花般的笑容");}}
}
class MyRunnable implements Runnable {                      //1,定义一个类,实现Runnable方法@Override   public void run() {                                     //2,重写run方法for (int i = 0; i < 100; i++) {                     //3,将要执行的代码写到run方法中System.out.println("我真的好想你,在每一个雨季。");           }}
}

两种方法的区别:

  • a.继承Thread : 由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法
  • b.实现Runnable : 构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空,编译时看的是Runnable的run(),运行时执行的时子类的run()方法

继承Thread(开发中优先考虑)

  • 好处:可以直接使用Thread类中的方法,代码简单

  • 弊端:如果已经有了父类,就不能有这个方法,因为java是单继承的

实现Runnable接口(实际上是对继承Thread的补充)

  • 好处:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,接口是可以多实现的,拓展性强

  • 弊端:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂

第三种方法是创建类是实现Callable这个接口。然后该类重写 Callable这个接口里的抽象方法call。

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

案例:通过实现Callable这个接口,来实现多线程,创建一个求和类;

具体的多线程实现代码如下:


package com.yy.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class Demo6_Callable {/*** 第三种线程创建方式* <T> Future<T> submit(Callable<T> task)* 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。* 该 Future 的 get 方法在成功完成时将会返回该任务的结果。 * Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。* * */public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService pool  = Executors.newFixedThreadPool(2);    //创建线程池,线程池里面可以养两个线程Future<Integer> f1 = pool.submit(new MyCallable(100));      //由于下面创建的类中里面有一个有参构造方法,这里得传一个参数Future<Integer> f2 = pool.submit(new MyCallable(50));//submit返回一个Future,所以说,应该用Future去接收//Future可以获取出来1-100或者是1-50的求和结果System.out.println(f1.get());System.out.println(f2.get());//V get()   throws InterruptedException,ExecutionException如有必要,等待计算完成,然后获取其结果。 pool.shutdown();                                            //关闭线程池}}
class MyCallable implements Callable<Integer>{                      //创建一个MyCallable类去实现Callable这个接口private int num;                                                //设置一个成员变量numpublic MyCallable (int num){                                    //创建一个有参构造方法this.num = num;                                             //num是传进去的数}@Overridepublic Integer call() throws Exception {                        //重写Callable这个接口里面的抽象方法call;这里的返回值类跟泛型<Integer>是一致的int sum = 0;                                                //实现求和代码for (int i = 1; i <= num; i++) {sum += i;}return sum;                                                 //返回sum}}

Java——多线程实现的三种方式相关推荐

  1. JAVA多线程实现的三种方式

    文章目录 继承Thread类实现多线程 实现Runnable接口方式实现多线程 区别 ExecutorService/Callable/Future实现有返回结果的多线程 步骤 概念 实例(可忽略) ...

  2. java开启一个线程_【jdk源码分析】java多线程开启的三种方式

    1.继承Thread类,新建一个当前类对象,并且运行其start()方法 1 packagecom.xiaostudy.thread;2 3 /** 4 * @desc 第一种开启线程的方式5 *@a ...

  3. JAVA多线程实现的三种方式 ()

    1.继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就 ...

  4. JavaEE多线程基本概念 及 创建多线程程序的三种方式

    Hello! 大家好.(非常平庸的开场白 习惯一下).此篇博客是我的"处女作",因为是第一次写博客,在文章格式以及文章内容可能会有许多问题和缺陷.欢迎各位大神对我的文章进行指正!我 ...

  5. Java实现数据共享的三种方式

    Java实现数据共享的三种方式 目录 文章目录 1.类的静态变量 2.类内声明共享数据类型的引用 3.内部类 ***后记*** : 内容 1.类的静态变量 示例:老师和学生共用一间教室 Classro ...

  6. java获取时间戳的三种方式比较

    文章目录 java获取时间戳的三种方式比较 java获取时间戳的三种方式比较 import java.util.Calendar; import java.util.Date; //不再推荐使用Dat ...

  7. Java数组定义的三种方式

    Java数组定义的三种方式 第一种:先声明,分配空间,赋值 int[] arr; //先声明arr=new int[10]; //分配空间fo0(int i=0;i<10;i++){arr[i] ...

  8. java多线程的实现方式_JAVA多线程实现的三种方式

    最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结. 1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用E ...

  9. java 创建线程_【80期】说出Java创建线程的三种方式及对比

    点击上方"Java面试题精选",关注公众号 面试刷图,查缺补漏 >>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅. 一.Ja ...

最新文章

  1. 详细讲解Hyper-V虚拟机的网络配置
  2. 使用UEFI Shell引导U盘启动
  3. drive es 软件兼容_某知名软件被完美修改!对不住了!
  4. db2 某个字段排序_MySQL、Oracle、DB2等数据库常规排序、自定义排序和按中文拼音字母排序...
  5. 精美UI版iApp对接hybbs论坛功能APP源码
  6. 让您的数据库服务器与您对话:直接从SQL Agent Jobs发送电子邮件
  7. maven-maven使用-P参数打包不同环境
  8. 傻傻弄不清楚SAP和ERP?
  9. mysql及格率公式_关于mysql进行名次的排名和计算及格率的分享
  10. 从春运迁徙图看疫情变化
  11. python 数据爬虫 爬取糗百
  12. 跨境电商虾皮值不值得做?你了解多少
  13. Q1:如何用 C# 计算相对时间 ?
  14. lightgbm可视化后的threshold和leaf_value是什么意思?
  15. 文科如何晋级计算机职称,职称的档次是怎么确定来的?
  16. 背单词APP调研分析
  17. 确定性随机数发生器测试向量——DRBG-HMAC-SHA1
  18. 未来已来让闲置回归价值
  19. Kali Linux修改更新源
  20. java 气泡_JAVA实现聊天气泡

热门文章

  1. Web前端体系的脉络结构
  2. vue+element 封装公共js代码
  3. Tomcat-部署多个项目(不同端口)
  4. 《Java技术》第二次作业计科1501赵健宇
  5. [回归分析][10]--相关误差的问题
  6. 138.括号序列(区间型DP)
  7. POJ3185(简单BFS,主要做测试使用)
  8. OSPF路由器建立全毗邻关系的状态转换过程
  9. [导入]一再的变故,终于决定何去何从.
  10. 轻云服务器的性能,腾讯云轻量应用服务器性能评测(以香港地域为例)