线程创建的几种方式
1、继承Thread类
启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。
import java.util.concurrent.TimeUnit;
public class demo1 {
public static void main(String[] args) {
myThread my = new myThread(); //创建子线程
my.setName("child thread"); //设置子线程的名字
my.start(); //子线程开启
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main is running");
}
}
class myThread extends Thread{ //继承Thread,设置自己的执行过程
@Override
public void run(){
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "is running");
}
}
}
2、实现Runnable接口
java只有单继承,但可以实现多个接口,实现Runnable接口创建线程相比上一种可以满足资源共享的需求。
import java.util.concurrent.TimeUnit;
public class demo2 {
public static void main(String[] args) throws InterruptedException {
myRunnable mr = new myRunnable(); //创建Runnable对象
Thread t = new Thread(mr,"child thread"); //将Runnabel对象注入Thread
t.start(); //开启线程
TimeUnit.SECONDS.sleep(1);
System.out.println("main thread is running");
}
}
class myRunnable implements Runnable{ //实现Runnable接口
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "is running");
}
}
}
3、实现Callable接口
无论是继承Thread类还是实现Runnable接口都无法获取线程执行的返回值。实现Callable接口创建线程可以获取线程执行的返回值,可以用于线程任务的分解。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class demo3 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
myCallable mc = new myCallable();
FutureTask<String> future = new FutureTask<>(mc); //将Callable对象注入FutureTask,FutureTask implements Runnable
new Thread(future,"child thread").start();
TimeUnit.SECONDS.sleep(1);
System.out.println(future.get()); //获取线程返回值
System.out.println("main thread is running");
}
}
class myCallable implements Callable<String>{ //实现Callable接口
@Override
public String call() throws Exception {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "is running");
}
return "success";
}
}
4、使用线程池
线程是宝贵资源,无限制地创建线程会造成资源的浪费,线程池的使用可以降低资源消耗、提高响应速度以及便于线程的管理。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class demo4 {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
service.execute(()->{
System.out.println(Thread.currentThread().getName() + "\tis running");
});
}
Thread.sleep(1000);
service.shutdown(); //关闭线程池
}
}