Java创建线程有好多种方法,但是本质上都是对Thread类的包装。
- 继承Thread
/**
* 第一种方法,继承Thread
*/
class Thread1 extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
/**
* 第一种方法,继承Thread
*/
public static void func1() {
new Thread1().start();
}
- 实现Runnable接口
/**
* 第二种方法,实现Runnable接口
* 之所以可以这么做,是因为Thread类有一个构造方法,参数是Runnable接口实现类,
* 其实Thread类本身也实现了Runnable接口,也就是说,第二种方法完全可以传入一个Thread的子类,
* 比如第一种方法实现的类,也能实现线程的创建。
*/
public static void func2() {
//直接实现Runnable接口
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
// 通过继承Thread实现Runnable接口
new Thread(new Thread1()).start();
}
- 实现callable接口
/**
* 方法三,通过实现Callable创建线程
* 实际上,Thread类没有一个构造函数可以接收Callable类型的参数
* 但是有一个FutureTask的构造方法,而FutureTask有一个接收Callable的构造方法
* 相当于借助FutureTask来创建线程
* @throws ExecutionException
* @throws InterruptedException
*/
public static void func3() throws ExecutionException, InterruptedException {
Callable<String> callable = new Callable<String>() {
@Override
public String call() {
return Thread.currentThread().getName();
}
};
FutureTask<String> task = new FutureTask<>(callable);
new Thread(task).start();
String result = task.get();
System.out.println(result);
}
- 使用线程池
/**
* 方法四,通过线程池创建线程
* Executors类有多个创建线程池的方法,这里是其中一种
* 也可以通过
* ThreadPoolExecutor(int corePoolSize,
* int maximumPoolSize,
* long keepAliveTime,
* TimeUnit unit,
* BlockingQueue<Runnable> workQueue)
* 这个构造方法来创建线程池,创建线程池也是实现Runnable接口,
* 只是启动线程的调用的方法和Thread类不一样,底层还是调用run类的方法
*/
public static void func4() {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}