介绍
api文档介绍
Thread 是Runnable的实现类,也可以说是其子类
进程是程序从开始到结束的过程
线程是进程进一步划分,是进程不同功能的具体实现
构造方法
Thread源码
public class Thread implements Runnable { 3 /* Make sure registerNatives is the first thing <clinit> does. */ 4 private static native void registerNatives(); 5 static { 6 registerNatives(); 7 } 8 9 private volatile String name; 10 private int priority; 11 private Thread threadQ; 12 private long eetop; 13 14 /* Whether or not to single_step this thread. */ 15 private boolean single_step; 16 17 /* Whether or not the thread is a daemon thread. */ 18 private boolean daemon = false; 19 20 /* JVM state */ 21 private boolean stillborn = false; 22 23 /* What will be run. */ 24 private Runnable target; 25 26 /* The group of this thread */ 27 private ThreadGroup group; 28 29 /* The context ClassLoader for this thread */ 30 private ClassLoader contextClassLoader; 31 32 /* The inherited AccessControlContext of this thread */ 33 private AccessControlContext inheritedAccessControlContext; 34 35 /* For autonumbering anonymous threads. */ 36 private static int threadInitNumber;
重写的run()
调用目标对象的run,否则什么都不做
1 /** 2 * If this thread was constructed using a separate 3 * <code>Runnable</code> run object, then that 4 * <code>Runnable</code> object's <code>run</code> method is called; 5 * otherwise, this method does nothing and returns. 6 * <p> 7 * Subclasses of <code>Thread</code> should override this method. 8 * 9 * @see #start() 10 * @see #stop() 11 * @see #Thread(ThreadGroup, Runnable, String) 12 */ 13 @Override 14 public void run() { 15 if (target != null) { 16 target.run(); 17 } 18 }
/* What will be run. */ private Runnable target;
线程的Start()
实际调用的是start0()方法,native声明,便是调用本机的操作系统,因为多线程的实现需要依靠底层操作系统的支持 Start0具体由JVM实现,最终是调pthread_create 系统方法来创建的线程,这里会从用户态切换到内核态完成系统资源的分配,线程的创建。
Thread的子类重写了run()方法,调用start()时,由于继承的关系,jvm自动调用的是子类的run()方法
对于实现了Runnable 的它的子类,通过带参Thread(Runnable 对象名)构造方法时便已将该子类对象赋值给了Thread的私有Runnable target对象,调用start时,run方法会判断该target对象是否为空,不为空的话,执行该traget的run方法1 /** 2 * Causes this thread to begin execution; the Java Virtual Machine 3 * calls the <code>run</code> method of this thread. 4 * <p> 5 * The result is that two threads are running concurrently: the 6 * current thread (which returns from the call to the 7 * <code>start</code> method) and the other thread (which executes its 8 * <code>run</code> method). 9 * <p> 10 * It is never legal to start a thread more than once. 11 * In particular, a thread may not be restarted once it has completed 12 * execution. 13 * 14 * start用于使线程开始执行,JVM会调用该线程的run() 15 * 结果是会有两个线程并发:start调用的线程,执行run的线程 16 * 不允许多次启动同一个线程 17 * 特别是,线程一旦完成就不能重新启动执行。 18 * 19 * 一个线程的start只能被调用一次=》线程的生命周期是单行道,不能重来,挂了就没了,但是可以新建线程 20 * 21 * 22 * @exception IllegalThreadStateException if the thread was already 23 * started. 24 * @see #run() 25 * @see #stop() 26 */ 27 public synchronized void start() { 28 /** 29 * This method is not invoked for the main method thread or "system" 30 * group threads created/set up by the VM. Any new functionality added 31 * to this method in the future may have to also be added to the VM. 32 * 33 * 线程状态为New,才能到start方法 34 * A zero status value corresponds to state "NEW". 35 */ 36 if (threadStatus != 0) 37 throw new IllegalThreadStateException(); 38 39 /* Notify the group that this thread is about to be started 40 * so that it can be added to the group's list of threads 41 * and the group's unstarted count can be decremented. */ 42 group.add(this); 43 44 boolean started = false; 45 try { 46 // 实际执行时start0,一个本地方法 47 start0(); 48 started = true; 49 } finally { 50 try { 51 if (!started) { 52 group.threadStartFailed(this); 53 } 54 } catch (Throwable ignore) { 55 /* do nothing. If start0 threw a Throwable then 56 it will be passed up the call stack */ 57 } 58 } 59 } 60 61 private native void start0();
为什么不能直接调用run()方法?
由start源码可知,线程的运行需要操作系统的支持
真正做事的是start0(0),native声明,便是调用本机的操作系统,因为多线程的实现需要依靠底层操作系统的支持
Start0具体由JVM实现,最终是调pthread_create 系统方法来创建的线程,这里会从用户态切换到内核态完成系统资源的分配,线程的创建,run方法也是JVM调用的。
直接调用run相当于调用一个普通方法而已,并不会创建线程 -参考java3y文章线程的四种创建方式
JDK8提供了9种Thread的构造方法
Thread的创建方式大体上分为4种
JDK1.5以前有两种
1,继承Thread类(因此可以直接通过对象名.start()的方式开启线程,受到单继承限制) (一个类继承了Thread类,此类就称为多线程操作类,必须明确的覆写run()方法)
2,实现Runnable接口(通过Thread(Runnable 对象名)接收Rannable对象来获取Thread对象,再调用start()方法开启线程)
【都是调用Thread对象的start()方法,1是通过Thread子类对象,2是传入runnable对象实例化Thread子类实例】
JDK1.5以后又有两种
3.因为引入了JUC,java util cancurrent。可以实现Callable接口,重写call方法 这个要说到FutureTask 同样来自JUC
4.可以使用线程池 一般是使用线程池
FutureTask实现了Runnable接口,能够用Callable构造
eg
1.直接继承Thread
1 // 多线程操作类
2 // 继承Thread:,直接通过Thread子类,实例化子类对象并调用start 3 class MyThread extends Thread{ 4 private String name; 5 Public MyThread(Strng name ){ 6 This.name=name; 7 }
// 明确的覆写run指名要进行的操作 8 public void run(){ 9 for(int i=0;i<10;i++){ 10 System.out.println(name+"运行,i="+"i"); 11 } 12 public class ThreadDemo{ 13 public static void main(String []args){ 14 MyThread m1=new MyThread("线程A"); 15 MyThread m2=new MyThread("线程B");
// 线程的执行从Start开始 16 m1.start(); 17 m2.start(); 18 } 19 }
2.实现Runnable接口
class A implements Runnable { static Integer count = 0; //重写run方法 @Override public void run() { for (int i = 0; i < 5; i++) { count++; System.out.println(Thread.currentThread().getName() + "\t" + count); } } } public class WithoutStatic { public static void main(String[] args) { A m1 = new A(); A m2 = new A(); //基于Thread的构造方法 Thread n1 = new Thread(m1); Thread n2 = new Thread(m2); n1.start(); n2.start(); } }
匿名内部类写法
public static void getVoid() { //不传入Runnable对象 new Thread(){ //重写run()方法 public void run() { for (int i = 0; i < 8; i++) { //业务逻辑写上 System.out.println("+++"+i); } } }.start(); }
new Thread(new Runnable() { @Override public void run() { //写上业务逻辑 for (int i = 0; i <5; i++) { System.out.println("======="+i); } } }).start();
标签:Runnable,run,Thread,private,start,线程 From: https://www.cnblogs.com/deity-night/p/17142909.html