1、创建线程的方式
- 继承Thread,重写run方法
- 实现Runnable接口,重写run方法
- 实现Callable接口,重写call方法(在执行完任务之后能够获取执行结果)
2、具体实现及使用
2.1、继承Thread,重写run方法
public class MyThread extends Thread {
@Override
public void run() {
for (int x = 0; x < 200; x++) {
System.out.println(x);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
// 创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
}
}
2.2、实现Runnable接口,重写run方法
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(x);
}
}
}
public class MyRunnableDemo {
public static void main(String[] args) {
// 创建MyRunnable类的对象
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
t1.start();
t2.start();
}
}
3、一些问题
3.1、run()和start()方法区别
- run():仅仅是封装被线程执行的代码,直接调用是普通方法,只会执行同一个线程中的任务,而不会启动新线程。
- start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
3.2、我们应该使用哪种方式创建线程
一般情况下通过实现Runnable接口创建线程,原因如下:
- 可以避免java中的单继承的限制
- 应该将并行运行任务和运行机制解耦合。如果通过继承Thread类创建,并且调用start()方法启动线程,那么当有很多任务时,要为每个任务创建一个独立的线程,代价太大。这个问题可以通过线程池解决。
当执行完任务后需要获取执行结果,可以通过实现Callable接口创建线程。