经过了对多线程的简单了解之后,现在来介绍如何创建多线程。在Java中,创建线程有使用Thread类创建和使用Runnable接口创建两种方法。
Thread类创建线程
首先我们需要创建一个新的线程类,这个线程类需要继承Thread并覆写其中的run()方法。
class MyThread extends Thread {
private String message;
public MyThread (String msg) {
this.message = msg;
}
@Override
public void run() {
System.out.println(message);
}
}
然后我们对主类进行书写,在主类中我们要调用start()方法。
public class test_thread {
public static void main(String[] args) {
new MyThread("线程1").start();
new MyThread("线程2").start();
new MyThread("线程3").start();
}
}
运行结果如下
显然并不是我们想象中的那样顺序输出“线程1、线程2、线程3”。不仅如此,每次的运行结果也可能不相同。
这是因为我们一共创建了三个线程,这三个线程必须去抢占CPU的资源,来决定谁先执行谁后执行。而并不是按照代码书写的顺序来执行的。
Runnable接口创建线程
Runnable接口创建线程的方法和Thread创建现成的方法类似,都要创建一个新的类,而这种方法是实现Runnable接口。
class MyThread implements Runnable {
private String message;
public MyThread (String msg) {
this.message = msg;
}
@Override
public void run() {
System.out.println(message);
}
}
但是对于主类的书写就有所不同了,我们不能够直接创建线程。我们需要先创建Thread类对象,然后再调用start()方法开启线程。
public class test_thread {
public static void main(String[] args) {
MyThread myThread1 = new MyThread("线程1");
MyThread myThread2 = new MyThread("线程2");
MyThread myThread3 = new MyThread("线程3");
Thread thread1 = new Thread(myThread1);
Thread thread2 = new Thread(myThread2);
Thread thread3 = new Thread(myThread3);
thread1.start();
thread2.start();
thread3.start();
}
}
我们对主类的写法还可以使用Lambda表达式进行书写。对于Lambda表达式不理解的朋友也不必担心,Lambda表达式可以通过集成编译器自动生成;也可以参考以下文章。
参考文章:
Lambda表达式(1)
Lambda表达式(2)
public class test_thread {
public static void main(String[] args) {
//原始写法
new Thread(new Runnable() {
@Override
public void run() {
MyThread myThread = new MyThread("线程1");
}
}).start();
//Lambda表达式
new Thread(() -> {
MyThread myThread = new MyThread("线程2");
}).start();
new Thread(() -> {
MyThread myThread = new MyThread("线程3");
}).start();
}
}
Thread与Runnable的区别与联系
继承Thread的类可以直接调用start()方法开启线程,而实现Runnable接口的类需要先创建Thread对象才可以调用start()方法开启线程。
对于这个原因的解释,我们可以从源码上来解释。
public interface Runnable {
public abstract void run();
}
上面是Runnable的源代码,我们可以看到它只有一个抽象方法。
public class Thread implements Runnable {}
这是Thread类的声明。
我们现在可以明确的知道,创建并开启线程需要也必须要用到Thread,而Thread又实现了Runnable的抽象方法。
而这两种方法的优劣我们不能仅仅通过代码的长度来进行比较。