解析java中创建并运行线程的三种方式
1 继承Thread类
1.1 核心思路
1.1.1 写一个自定义类继承(extends) Thread类
1.1.2 重写Run方法,里面写线程执行过程中的业务逻辑
1.1.3 实例化自定义类,得到对象a(创建了一个线程,new的状态)
1.1.4 a.start()方法去启动线程(ready状态---->就绪)
1.2 示例代码
Cat类
package Work4;
public class Cat extends Thread{
/*一定要重写Thread类里面的Run方法
因为不写的话默认就是调用父类型特征区里面的run方法
我们创建并启动线程,是需要写自己独有的业务逻辑,因此就必须重写它
这个地方不重写也不会报错,因此需要特别关注一下
*/
@Override
public void run() {
int count=0;
while(count<10){
System.out.println("线程名"+Thread.currentThread().getName()+"的小猫咪正在喵喵喵"+(++count));
}
}
}
ThreadTest类
package Work4;
public class ThreadTest {
public static void main(String[] args) {
Cat cat=new Cat();
cat.start();
}
}
1.3 示例代码运行截图
2 实现Runnable接口
2.1 核心思路
2.1.1 写一个自定义类实现Runnable接口
2.1.2 重写Runnable接口的run方法,书写线程自己的业务逻辑
2.1.3 实例化自定义类,得到对象a
2.1.4 实例化Thread类,在实例化的过程中把对象a通过构造方法(Runnable target)传入进去,得到对象t
2.1.5 t.start()方法
2.2 示例代码
Cat类
package Work4;
public class Cat implements Runnable{
@Override
public void run() {
int count=0;
while(count<10){
System.out.println("线程名"+Thread.currentThread().getName()+"的小猫咪正在喵喵喵"+(++count));
}
}
}
ThreadTest类
package Work4;
public class ThreadTest {
public static void main(String[] args) {
//实例化自定义类,该类实现了Runnable接口
Cat cat=new Cat();
//实例化Thread类(线程类),在实例化的过程中将cat对象传入进去
Thread thread = new Thread(cat);
thread.start();
}
}
2.3 示例代码运行截图
3 匿名内部类实现
3.1 核心思路
3.1.1 实例化一个Thread类,得到对象t
3.1.2 在实例化的过程中传入一个匿名类,该类实现了Runnable接口
3.1.3 t.start()方法
3.2 示例代码
ThreadTest类
package Work4;
public class ThreadTest {
public static void main(String[] args) {
//采用匿名内部类的方式
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int count=0;
while(count<10){
System.out.println("线程名"+Thread.currentThread().getName()+"的小猫咪正在喵喵喵"+(++count));
}
}
});
thread.start();
}
}
3.3 示例代码运行截图
4 总结
4.1 这三种方法都是和Thread类有关,都一定要重写run方法,在run方法里面写入自己的业务逻辑
4.2 可以用run方法启动线程吗?
4.2.1 分析
不能,去调用run方法的过程中本质上就是调用一个普通方法,启动线程的方法是start方法,他在底层调用了start0方法(启动线程的关键方法)
4.2.2 底层源码
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".
*/
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();
//本质是这个方法启动了线程
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 */
}
}
}
private native void start0();
//被native修饰的方法代表是用c/c++实现的代码
4.3 使用继承Thread类这种方式去创建并启动线程,一定要重写run方法,不可忘记,因为你不重写它也不会有任何提示
4.4 一般来说,使用实现Runnable接口的方法去创建并启动线程用到比较多,我们写程序也应该首选它,因为它能有效避免java单继承的缺点