创建线程的三种方式是啥?
在我们日常开发中多线程是必不可少的,那么线程的创建也就成了面试中的高频问题,决定整理一下;如有错误还请个位指正!
文章目录
写在前面
一般创建线程常用继承Thread类和实现Runnable接口两种方式,当然也可以使用ExecutorService、Callable、Future实现有返回结果的多线程;这里主要介绍前两种;
继承Thread类实现多线程
一个类只要继承了Thread就是多线程的实现类,必须重写run方法;
步骤:
自定义一个类,这个类继承自Thread类
在这个类重写Thread类中的run方法(一般存储耗时的代码)
在主线程中开启子线程 main线程
- 创建自定义线程类对象
- 使用线程类对象调用start()方法
public class TestExtendsThreads {
public static void main(String[] args) {
//创建线程对象
MyThread1 t1 = new MyThread1();
t1.start();//线程启动(JVM调用run方法)
for(int i = 1; i<50; i++){
System.out.println("Main:"+i);
}
}
}
//线程类 自定义线程
class MyThread1 extends Thread{
public void run(){
//线程的执行具有随机性,存储"耗时代码"
for(int i = 1; i<50; i++){
System.out.println("MyThread1:"+i);
}
}
}
实现Runnable接口方式实现多线程
只需要实现一个抽象方法:public void run();
步骤:
自定义一个类 , 实现 Runnable接口
实现接口中提供的功能:public abstract void run() ; 比较耗时的操作
用户线程main,创建资源类对象
- 创建Thread类对象,将上面对象作为参数传递
- 分别启动线程
Thread类的构造方法
public Thread(Runnable target):分配一个新的Thread对象
public Thread(Runnable target, String name):分配一个新的Thread对象
Thread.currentThread():获取正在运行的线程
public class TestImplementsRunnable {
public static void main(String[] args) {
//创建资源类对象象
MyRunnable mr1 = new MyRunnable();
//创建线程类对象
Thread t1 = new Thread(mr1);
Thread t2 = new Thread(mr1);
//分别启动线程
t1.start();
t2.start();
for(int i = 1; i<50; i++){
System.out.println("Main:"+i);
}
}
}
class MyRunnable implements Runnable{
public void run(){
for(int i = 1; i<50; i++){
//Thread.currentThread()正在运行的线程
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
- Runnable接口必须要定义一个run的无参数方法
- 实现接口,只是将当前类编成任务类,本身不是个线程
- 更灵活、提供了能力、不影响继承
使用实现Callable接口的方式
步骤:
创建线程池对象: ExecutorService pool = Executors.newFiexdThreadPool(int nThreads){}
提交异步任务 submit(Callable call)
- Callable:接口 (Functional Interface:函数式接口:接口中只有一个抽象方法)
- V call():计算结果
关闭资源:shutdown():关闭线程池资源对象
public class MyCallable implements Callable {
@Override
public Object call() throws Exception{
for(int i = 0 ;i < 200; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
return null;
}
}
public static void main(String[] args) {
//创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(2);
//提交异步任务
pool.submit(new MyCallable());
pool.submit(new MyCallable());
//关闭资源
pool.shutdown();
}