多线程有哪几种创建方式
1、继承Thread创建线程
继承java.lang.Thread类,重写run()方法,在run()方法中实现运行在线程上的代码,调用start()方法开启线程
本质上是实现了Runnable接口的一个实例,代表一个线程的实例,启动线程的唯一方法是通过start()方法,它是一个native方法,启动一个新线程,并执行run()方法
class MyThread extends Thread {
@Override
public void run() {
System.out.println("我是继承Thread创建的线程:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("我是主线程:" + Thread.currentThread().getName());
new MyThread().start();
new MyThread().start();
}
运行结果
我是主线程:main
我是继承Thread创建的线程:Thread-0
我是继承Thread创建的线程:Thread-1
重写run()方法,无返回值
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("我是实现Runnable创建的线程:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("我是主线程:" + Thread.currentThread().getName());
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
}
运行结果
我是主线程:main
我是实现Runnable创建的线程:Thread-0
我是实现Runnable创建的线程:Thread-1
重写call()方法,有返回值,可以抛出异常被捕获
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "我是实现Callable创建的线程:" + Thread.currentThread().getName();
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("我是主线程:" + Thread.currentThread().getName());
MyCallable myCallable1 = new MyCallable();
MyCallable myCallable2 = new MyCallable();
FutureTask<String> futureTask1 = new FutureTask<>(myCallable1);
FutureTask<String> futureTask2 = new FutureTask<>(myCallable2);
new Thread(futureTask1).start();
new Thread(futureTask2).start();
try {
System.out.println(futureTask1.get());
System.out.println(futureTask2.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
}
运行结果
我是主线程:main
我是实现Callable创建的线程:Thread-0
我是实现Callable创建的线程:Thread-1
线程和数据库连接这些资源都是非常宝贵的,如果我们每次需要的时候创建,不需要的时候销毁,是非常浪费的,我们可以使用缓存策略,也就是使用线程池
public static void main(String[] args) throws InterruptedException {
System.out.println("我是主线程:" + Thread.currentThread().getName());
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(() -> System.out.println("我是线程池创建的线程:" + Thread.currentThread().getName()));
executorService.execute(() -> System.out.println("我是线程池创建的线程:" + Thread.currentThread().getName()));
}
运行结果
我是主线程:main
我是线程池创建的线程:pool-1-thread-1
我是线程池创建的线程:pool-1-thread-2
下面两种写法,本质上都是实现Runnable接口,重写run()方法,第二种使用的Lambda表达式
public static void main(String[] args) throws InterruptedException {
System.out.println("我是主线程:" + Thread.currentThread().getName());
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是匿名内部类创建的线程:" + Thread.currentThread().getName());
}
}).start();
new Thread(() -> System.out.println("我是匿名内部类创建的线程:" + Thread.currentThread().getName())).start();
}
运行结果
我是主线程:main
我是匿名内部类创建的线程:Thread-0
我是匿名内部类创建的线程:Thread-1