实现方式
第一种 继承Thread类
自定义类,继承Thread类,并重写run()方法.
class MyThread1 extends Thread {
@Override
public void run() {
System.out.println("第一种方式Thread " + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
//第一种方式
MyThread1 thread1 = new MyThread1();
thread1.start();
MyThread1 thread1 = new MyThread1();
thread1.start();
MyThread1 thread2 = new MyThread1();
thread2.setName("zz");
thread2.start();
// 运行结果
// 第一种方式Thread Thread-0
// 第一种方式Thread Thread-1
// 第一种方式Thread zz
// 若不指定Name属性,能默认计数器0,1,2,3,4,5
}
}
第二种 实现Runnable接口
自定义类,实现Runnable接口的run方法. since JDK1.0
class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("第二种方式Runnable " + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
//第二种方式
Thread thread2 = new Thread(new MyThread2());
thread2.start();
// Lambda表达式方式->因为Runnable被注解FunctionalInterface标识表明该接口是一个函数式接口
new Thread(() -> {
System.out.println("第二种方式Runnable_Lambda " + Thread.currentThread().getName());
}).start();
// 运行结果
// 第二种方式Runnable Thread-0
// 第二种方式Runnable_Lambda Thread-1
}
}
第三种 实现Callable接口
已知Runnable的run方法无返回值,所以引入了有返回值的Callable接口
since JDK1.5
-
FutureTask中构造方法如下.
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }
-
FutureTask类结构图如下.
-
因为FutureTask类实现了Runnable接口,所以线程实现方法如下.
public class Test { public static void main(String[] args) throws Exception { //第三种方式 FutureTask<String> thread3 = new FutureTask<>(new MyThread3()); new Thread(thread3).start(); System.out.println(thread3.get()); //获得回调值 FutureTask<String> thread4 = new FutureTask(()->{ System.out.println("Call"); return "Lambda回调"; }); new Thread(thread4).start(); System.out.println(thread4.get()); // 运行结果 // 第三种方式Callable Thread-0 // 回调 // Call // Lambda回调 } } class MyThread3 implements Callable<String> { @Override public String call() throws Exception { System.out.println("第三种方式Callable " + Thread.currentThread().getName()); return "回调"; } }
第四种 线程池
交付线程池两种方式 submit或者execute方法,前者可接受Callable接口对象,有返回值,后者无返回值
public class Test {
public static void main(String[] args) throws Exception {
//第一种方式
MyThread1 thread1 = new MyThread1();
thread1.start();
//第二种方式
Thread thread2 = new Thread(new MyThread2());
thread2.start();
//第三种方式
FutureTask<String> thread3 = new FutureTask<>(new MyThread3());
new Thread(thread3).start();
System.out.println(thread3.get());
//第四种方式
ExecutorService pool = Executors.newFixedThreadPool(5);
Future<?> submit1 = pool.submit(new MyThread1());
Future<?> submit2 = pool.submit(new MyThread2());
Future<?> submit3 = pool.submit(new MyThread3());
System.out.println(submit1.get() + " " + submit2.get() + " " + submit3.get());
pool.shutdown();
// 运行结果
// 第一种方式Thread Thread-0
// 第二种方式Runnable Thread-1
// 第三种方式Callable Thread-2
// 回调
// 第一种方式Thread pool-1-thread-1
// 第二种方式Runnable pool-1-thread-2
// 第三种方式Callable pool-1-thread-3
// null null 回调
}
}
特点
- 无论何种方式,都要使用Thread类中start方法开始多线程.
- Runnable接口和Callable接口区别,后者可返回参数,参数类型Object.
- 线程池避免了线程频繁使用的创建和释放操作.
转载:https://blog.csdn.net/weixin_43502533/article/details/106163515
查看评论