网站推广费用入什么科目,网上服务大厅12333,百度竞价广告点击器,编程培训机构排名前Java多线程-Thread类的run方法 一、背景二、研究Thread类的start()源码1、源码#xff08;比较短#xff0c;贴一下#xff09;1.1 重点#xff1a;start0(); 三、研究Thread类的run()源码1、源码#xff08;很关键#xff0c;必须贴#xff09; 四、创建线程的2种方式1… Java多线程-Thread类的run方法 一、背景二、研究Thread类的start()源码1、源码比较短贴一下1.1 重点start0(); 三、研究Thread类的run()源码1、源码很关键必须贴 四、创建线程的2种方式1、继承Thread并覆写run方法2、传入一个实现了run方法的Runnable接口的实现类 五、到底执行哪个run方法 一、背景
在Java中要使用多线程很显然先要创建线程。Java将线程抽象为Thread类。创建线程的第一步new Thread()创建好Thread对象后接下来就是要启动线程并执行线程需要做的事情Thread对象.start(); 1首先会启动线程 2然后调用run方法();
二、研究Thread类的start()源码
1、源码比较短贴一下
public synchronized void start() {if (threadStatus ! 0)throw new IllegalThreadStateException();group.add(this);boolean started false;try {start0();started true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {}}
}1.1 重点start0();
源码
private native void start0();是一个本地方法。也很好理解Java的线程是交由操作系统来管理的。 start0()方法是Java中的一个本地方法也就是说它是用其他语言通常是C或C实现的。 其主要逻辑是创建一个新的系统级线程并在新线程上执行run()方法。 Java中的线程是基于操作系统的原生线程实现的而start0()方法主要就是与操作系统进行交互创建和启动新的系统级线程。 具体来说start0()方法的执行逻辑一般包括以下步骤 1申请系统资源创建一个新的系统级线程。 2将Java线程对象与新创建的系统级线程进行关联。 3设置线程的优先级和栈大小等线程属性。 3在新的系统级线程上调用Java线程对象的run()方法。 4如果run()方法执行结束或发生异常清理系统级线程资源。 以上执行逻辑可能因不同的JVM实现和不同的操作系统有所不同具体实现代码可以在JVM的源代码中找到。 三、研究Thread类的run()源码
1、源码很关键必须贴
Override
public void run() {if (target ! null) {target.run();}
}Thread类public class Thread implements Runnable
Runnable的源码
FunctionalInterface
public interface Runnable {public abstract void run();
}既然Thread类实现了Runnable接口就要覆写run方法。
target是什么
public class Thread implements Runnable {......private Runnable target;......
}用户可以通过这个构造方法传入target
public Thread(Runnable target) {init(null, target, Thread- nextThreadNum(), 0);
}四、创建线程的2种方式 通过上面的分析要让线程执行某段逻辑的关键是实现run方法。 有2种方式 1继承Thread并覆写run方法 2传入一个实现了run方法的Runnable接口的实现类 1、继承Thread并覆写run方法
示例
public class PrintEvenThread extends Thread {Overridepublic void run() {// 遍历100以内的偶数for (int i 0; i 100; i) {if (i % 2 0) {System.out.println(Thread.currentThread().getName() : i);}}}
}public class PrintOddThread extends Thread {Overridepublic void run() {// 遍历100以内的奇数for (int i 0; i 100; i) {if (i % 2 ! 0) {System.out.println(Thread.currentThread().getName() : i);}}}
}public class PrintThreadTest {Testpublic void testTwoPrintThread() {PrintEvenThread printEvenThread new PrintEvenThread();PrintOddThread printOddThread new PrintOddThread();printEvenThread.start();printOddThread.start();}
}还可以匿名类的匿名对象的方式
new Thread() {Overridepublic void run() {for (int i 0; i 100; i) {if (i % 2 ! 0) {System.out.println(Thread.currentThread().getName() : i);}}}
}.start();2、传入一个实现了run方法的Runnable接口的实现类
示例 匿名类的匿名对象
public class LearnCreateThreadMain3 {public static void main(String[] args) {new Thread(new PrintEven()).start();}
}class PrintEven implements Runnable {Overridepublic void run() {for (int i 0; i 10; i) {if (i % 2 0) {System.out.println(i);}}}
}还可以匿名类的匿名对象的方式
new Thread(new Runnable() {Overridepublic void run() {for (int i 0; i 100; i) {if (i % 2 ! 0) {System.out.println(Thread.currentThread().getName() : i);}}}}).start();五、到底执行哪个run方法
示例
public class LearnCreateThreadMain4 {public static void main(String[] args) {Hi hi new Hi();new Thread(hi) {Overridepublic void run() {System.out.println(hello~);}}.start();}
}class Hi implements Runnable {Overridepublic void run() {System.out.println(Hi~);}
}看懂了“三、研究Thread类的run()源码”很容易回答执行的是Thread子类对象的run方法。也就是输出hello~。如果子类没有覆写Thread的run()方法那么执行的代码是
Override
public void run() {if (target ! null) {target.run();}
}一旦子类覆写了那执行的就是子类的run()方法了。