多线程---创建线程的七种方式
文章目录
- 继承Thread类,重写run方法
- 实现Runnable接口,重写run方法
- 使用匿名内部类,创建Thread子类
- 使用匿名内部类,实现Runnable接口
- 使用lambda表达式
- 使用线程池(后续详细介绍)
- 使用Callable接口(后续详细介绍)
我们已经知道:线程是为了提高程序的执行效率的。那我们一个怎样创建一个线程来使用呢? 在这里给大家介绍七种创建线程的方式!
继承Thread类,重写run方法
class MyThread extends Thread{
@Override
public void run() {
while (true){
System.out.println("继承Thread类,重写run方法");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
注:
- 将线程和线程要做的工作绑定在一起,通过start方法启动线程、执行工作。
- 想要添加新的工作,就必须创建一个新的线程类。
实现Runnable接口,重写run方法
class MyRunnable implements Runnable{
@Override
public void run() {
while (true){
System.out.println("实现Runnable接口,重写run方法");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
}
}
注:
- 把线程和线程要做的工作分离开,把Runnable对象以参数的形式放到线程中,这样会自动重写Thread的run方法,通过start方法启动线程、执行工作。
- 想要添加新的工作还是得创建新的类实现接口;但是要求多个线程执行一个工作时直接使用即可。
使用匿名内部类,创建Thread子类
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(){
@Override
public void run() {
while (true){
System.out.println("使用匿名内部类,创建Thread子类");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
}
注:
- 这是第一种方式的简单写法,省略了第一种方式还得专门创建一个类的过程。
- 将线程和工作绑定在一起,想要添加新的工作得创建新的线程。
使用匿名内部类,实现Runnable接口
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println("使用匿名内部类,实现Runnable接口");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
}
注:
- 这是第二种方式的简单写法,省略了第二种方式还得专门创建一个类实现Runnable接口的过程。
- 将线程和工作绑定在一起,想要添加新的工作得创建新的线程;想要执行同一个工作也得创建新的线程。
使用lambda表达式
lambda表达式只是一个简单的“语法糖”,它的存在是让代码写起来更加简单、方便。
lambda表达式本质上是一个“匿名函数”,():函数的形参、{}:函数体、->:特殊语法,表示它是一个lambda。
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (true){
System.out.println("这是lambda表达式");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
注:每次在执行某个任务时,都得创建新的线程。
使用线程池(后续详细介绍)
public class Test {
public static void main(String[] args) {
//创建一个线程数目动态增长的线程池
ExecutorService pool = Executors.newCachedThreadPool();
//创建一个固定线程数的线程池
ExecutorService pool1 = Executors.newFixedThreadPool(5);
//创建一个只包含单个线程的线程池
ExecutorService pool2 = Executors.newSingleThreadExecutor();
//创建一个定期执行命令的线程池
ExecutorService pool3 = Executors.newScheduledThreadPool(5);
pool.submit(new Runnable() {
@Override
public void run() {
while (true){
System.out.println("这是线程池");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
}
注:
- 创建线程池有四种方式,我们要根据应用场景选择合适的方式进行创建。
- 通过submit方法往线程池里添加工作,可以通过submit提交多个工作,添加到线程池中后线程池会自动开始执行。
使用Callable接口(后续详细介绍)
public class Test {
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
while (true){
System.out.println("这是 Callable");
Thread.sleep(1000);
}
}
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
}
}
注:
- 创建Callable重写call方法,用来定义工作。
- 按理说应该把工作,即Callable对象,直接放到Thread里执行不就行了? 但是这里不行。因为Thread的参数在设计时没有添加Callable,所以需要借助一个中间量来把他们俩联系起来,这个中间量就是FutureTask。