博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程的启动的两种方法,Runnable接口,run()的调用
阅读量:4669 次
发布时间:2019-06-09

本文共 4876 字,大约阅读时间需要 16 分钟。

实现并启动线程有两种方法

1、写一个类继承自Thread类,重写run方法。用start方法启动线程
2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动
多线程原理:相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。
调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。
1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。

记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发

1 public class Test {   2     public static void main(String[] args) {   3         Runner1 runner1 = new Runner1();   4         Runner2 runner2 = new Runner2();   5 //      Thread(Runnable target) 分配新的 Thread 对象。   6         Thread thread1 = new Thread(runner1);   7         Thread thread2 = new Thread(runner2);   8 //      thread1.start();   9 //      thread2.start();  10         thread1.run();  11         thread2.run();  12     }  13 }  14   15 class Runner1 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程  16     public void run() {  17         for (int i = 0; i < 100; i++) {  18             System.out.println("进入Runner1运行状态——————————" + i);  19         }  20     }  21 }  22   23 class Runner2 implements Runnable { // 实现了Runnable接口,jdk就知道这个类是一个线程  24     public void run() {  25         for (int i = 0; i < 100; i++) {  26             System.out.println("进入Runner2运行状态==========" + i);  27         }  28     }  29 }

以上整理来自:http://blog.csdn.net/xuxurui007/article/details/7685076

 

【线程的创建和启动的步骤实现Runnable接口方式)】

1.定义Runnable接口的实现类,并重写其中的run方法。run()方法的方法体线程执行体

   class SonThread  implement Runnable{

  public void run(){

  ......

  }

 }

2.创建Runnable接口实现类的实例。                        sonThread s1=new SonThread();

3.用该实例作为Thread的target来创建Thread对象。   Thread t1 =new Thread(s1);

4.调用该对象的start()方法启动线程。                       t1.start();

 

【注意一:关于命名】

在创建Thread 对象的时候可以为该Thread对象指定一个名字

【注意二:Thread的构造方法】

Runnable对象作为Thread对象的target,Runnable实现类里面包含run方法仅仅作为执行体。也就是说Thread类的作用是把run方法包装成线程的执行体。

实际运行的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run方法。

1 //1.1定义Runnable接口的实现类 2 class SecondThread implements Runnable{ 3  4     //1.2重写其中的run方法 5     @Override 6     public void run() { 7         for(int i=0;i<10;i++){ 8             System.out.println(Thread.currentThread().getName()+"===="+i); 9         }10     }11     12 }13 public class Demo2 {14     15     public static void main(String[] args) {16         //2.创建Runnable的接口实现类的实例17         SecondThread s1=new SecondThread();18         SecondThread s2=new SecondThread();19         //2.用Runnable的接口实现类的实例作为Thread的target,创建Thread对象20         Thread t1=new Thread(s1);21         Thread t2=new Thread(s2,"Higgin");  //创建Thread对象的同时可以为之命名22         23         //启动线程24         t1.start();25         t2.start();26         27         for(int i=0;i<10;i++){28             System.out.println(Thread.currentThread().getName()+"===="+i);29         }30     }31 }

以上整理来自:http://www.cnblogs.com/HigginCui/p/5901593.html

 

代码1:

1 new Thread(new Runnable() {   2     @Override   3     public void run() {   4         System.out.println("Run of Runnable");   5     }   6 }) {   7     public void run() {   8         System.out.println("Run of Thread");   9     }  10 }.start();

代码2:

1 new Thread(new Runnable() {   2     @Override   3     public void run() {   4         System.out.println("Run of Runnable");   5     }   6 }) {   7     public void run() {   8         System.out.println("Run of Thread");   9         super.run();  10     }  11 }.start();

首先,我们来看一下JDK的Thread源码,片段 3 如下:

1 private Runnable target;
public void run() {      if (target != null) {          target.run();      }  }

在run()方法中,首先会检查target是否为空,如果不是,则执行该target的run()方法。

那么,对于上面两段代码的执行,也就清楚了。

在第一个代码段 1 中,重写了Thread的run()方法,同时传入了一个Runnable对象,该对象也实现了run()方法。该Thread对象调用start()方法后,会执行该对象重写的run()方法,其输出结果也就是Run of Thread,输出完后,run()方法返回,该线程对象的生命周期也就结束了。

在第二个代码段 2 中,同样也重写了Thread的run()方法,同时传入了一个Runnable对象,实现了run()方法。唯一不同的是,在Thread重写的run方法中,在打印输出后,还执行了super.run(),这就有意思了。

首先,该线程启动运行后,执行其重写的run()方法,输出Run of Thread。

接下来调用super.run(),也就是调用超类的run()方法,而该超类的run()方法,也就是JDK定义的Thread类的run(),其执行如上代码段 3 所示;显然target不为空,这时候会调用该对象的run()方法,会输出Run of Runnable.。

如果,上面的Thread并未重写run()方法,那么,执行的结果还是一样。首先会执行该Thread的run()方法,因为此时并未重写该方法,所以还是会调用JDK定以的run()方法,也就是上面的代码段 3,在该代码段中会判断target是否为空,显然不是,所以会调用Runnable对象实现的run()方法。

总结:对于Thread(Runnable target ...),不管传入的Target是否为空,首先都会执行Thread自己的run()方法。如果重写了该方法且该方法中没有super.run(),那么是永远不会调用Runnable实现的run()方法;如果没有重写该方法,则会去判断target是否为空,以此来决定调用target实现的run()方法;如果重写了该方法,且该方法中有super.run(),在执行完该语句之前的所有代码后,会判断target是否为空,以此来决定调用target实现的run()方法,执行完后,接着执行该语句之后的代码。

以上整理来自:http://blog.csdn.net/guguituzi/article/details/44593863

转载于:https://www.cnblogs.com/echo-cheng/p/6814909.html

你可能感兴趣的文章
ubuntu下安装JDK
查看>>
【C#】使用DWM实现无边框窗体阴影或全透窗体
查看>>
【MySql】脚本备份数据库
查看>>
keil5 配置 stm32f103rc 软件仿真
查看>>
RESTful到底是什么玩意??
查看>>
Oracle创建视图的一个问题
查看>>
(一)线性表
查看>>
hdu 1003 Max Sum (DP)
查看>>
mysql增备
查看>>
[APIO2015]雅加达的摩天楼
查看>>
andorid之帧布局FrameLayout
查看>>
(转,记录用)jQuery页面加载初始化的3种方法
查看>>
C++常量的引用 const
查看>>
51nod 1101 换零钱 【完全背包变形/无限件可取】
查看>>
python单例设计模式(待补充)
查看>>
Binary Tree Inorder Traversal
查看>>
HDU 1394 Minimum Inversion Number (数据结构-线段树)
查看>>
ansible-playbook && Roles && include
查看>>
String s String s=null和String s="a"区别
查看>>
[Alpha阶段]第二次Scrum Meeting
查看>>