线程八大基础核心二(启动线程)
在java多线程并发编程中,有八大基础核心。考考你:看看都有哪八大基础核心呢?它们分别是:
1.创建线程的方式
2.线程启动
3.线程停止
4.线程生命周期
5.线程相关的方法
6.线程相关的属性
7.线程异常处理
8.线程安全
今天我们从第二个基础核心开始:启动线程
#前情回顾:
1.在java编程语言中,创建好线程对象后,通过调用start方法,启动线程
Thread t1 = new Thread();
t1.start();
#考考你:
1.问题一:可以调用两次start方法吗?
2.问题二:可以调用run方法,启动线程吗?
package com.anan.thread.startthread; /** * 两次调用start方法,启动线程 */ public class TwoStartMethodDemo { public static void main(String[] args) { // 创建Runnable和Thread对象 Runnable r1 = new MyRunnable(); Thread t1 = new Thread(r1); // 调用两次start方法 t1.start(); t1.start(); } } /** * 实现Runnable方式,创建线程 */ class MyRunnable implements Runnable{ public void run() { System.out.println("两次调用start方法启动线程"); } }
package com.anan.thread.startthread; /** * 直接调用run方法启动线程 */ public class RunMethodDemo { public static void main(String[] args) { // 创建Runnable和Thread对象 Runnable r1 = new MyRunnable2(); Thread t1 = new Thread(r1); // 调用run方法 t1.run(); } } /** * 实现Runnable方式,创建线程 */ class MyRunnable2 implements Runnable{ public void run() { System.out.println("调用run方法启动线程,当前线程:"+Thread.currentThread().getName()); } }
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() * *注释:启动线程start方法源码,启动线程的流程是: * 第一:判断当前线程状态 * 第二:将当前线程加入线程组 * 第三:调用本地方法start0(),启动新线程 */ public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ // 第一:判断当前线程状态,如果不是NEW,则抛出非法线程状态异常 if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ // 第二:将当前线程加入线程组 group.add(this); boolean started = false; try { // 第三:调用本地方法start0(),启动新线程 // 彩蛋:java编程语言的线程实现,是基于操作系统【内核】线程的方式实现 start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) * *注释:运行线程run方法源码,在方法内部: * 第一:调用了target对象的run方法 * 第二:target对象是Runnable对象,相当于普通对象调用方法 * 第三:因此不会开启新的线程,还是在主线程main中执行 */ @Override public void run() { if (target != null) { target.run(); } }
#线程启动流程:
1.在java编程语言中,正确的启动线程方式,是调用start方法
2.在start方法内部启动流程是:
2.1.判断当前线程状态,是否是NEW状态
2.2.如果当前线程是NEW状态,将当前线程加入线程组
2.3.调用本地方法start0(),开启线程
#考考你答案:
1.可以调用两次start方法吗?
答案:不能,因为线程只有在NEW状态下,可以启动
2.可以调用run方法,启动线程吗?
答案:不能,因为直接调用run方法,相当于在主线程main下调用普通方法,并没有开启新的线程
我们唯一能够控制的是自己的脾气和努力