Runnable接口
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
衍生知识点:@FunctionalInterface 函数式接口
Thread类介绍
public class Thread implements Runnable {
...
@Override
public void run() {
if (target != null) {
target.run();
}
}
...
}
target是一个Runnable对象,如果不为null,则调用其run方法。
target是在init方法中初始化的,所有构造函数都会调用init。因此下面看下Thread类有哪些构造函数:
init函数:
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals);
Thread类的构造函数:
Thread()
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
Thread(ThreadGroup group, String name)
基本方法:
void start();
void run();
如果构造时未传递Runnable对象,则调用run方法直接返回,否则执行Runnable对象的run方法
run方法一般不需要显示调用(JVM会帮你调用),只需要调用start方法即可;如果直接调用run方法,会在原线程中执行,并不会新起线程
使用方法
- 继承Thread类,重写run方法
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("my thread extends java.lang.Thread");
}
}
new MyThread().start();
2.实现Runnable接口,重写run方法
public class MyThread2 implements Runnable{
public void run() {
System.out.println("my thread implements java.lang.Runnable");
}
}
new Thread(new MyThread2()).start();
- 匿名类的写法(实质是1,2)
new Thread(new Runnable() {
public void run() {
System.out.println("Runnable run");
}
}).start();
new Thread() {
@Override
public void run() {
System.out.println("Thread run");
}
}.start();
4、Java8 lambda写法(实质是2)
new Thread(() -> System.out.println("lambda")).start();
2种创建线程方法的区别、优劣
Thread类:
- 只能继承一个类,因此继承了Thread类,就不能继承别的类了
Runnable接口:
- 避免了继承的局限;
- 适合资源共享,适合多个相同的程序代码的线程去处理同一个资源。(MyThread中10张票,起3个线程卖,最终卖10张。如果是继承Thread类的方法,MyThread中10张票,3个线程最终会卖30张票)
- 线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
相关内容
- 函数式接口@FunctionalInterface
- Java Thread:揭开Run方法被调用的真正面纱 (TODO)
- 线程状态 (TODO)
- join、sleep、yield、notify区别 (TODO)
- 线程池 (TODO)
网友评论