Java中的线程是一种独立执行的路径,用来实现并发执行的程序。线程可以被看作是在程序中独立运行的一段代码,它能够同时执行多个任务。
在Java中,线程可以通过以下四种方式实现:
1.继承Thread类
可以创建一个继承自java.lang.Thread类的子类,并重写其中的run()方法,将需要并发执行的代码逻辑写在run()方法中。然后通过创建子类的实例调用start()方法来启动线程。
public static class MyThread extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + ">>>>>>>这是继承Thread
类");
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 继承Thread类
MyThread myThread = new MyThread();
myThread.setName("我的线程");
myThread.start();
}
2.实现Runnable接口
使用匿名类:可以使用匿名类的方式创建线程。
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 实现Runnable
Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ">>>>>>这是实现了Runnable
接口");
});
thread.start();
}
3.实现Callable接口
使用Callable
接口可以创建可以返回结果的线程。Callable
接口是java.util.concurrent
包中的一个接口,它定义了一个带有返回值的call()
方法。通过使用Callable
接口,可以在任务完成后返回结果,而Runnable
接口只能执行任务而没有返回结果。
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 实现Callable
FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + ">>>>>>这是实现了Callable接口");
return "1";
}
});
Thread thread1 = new Thread(futureTask);
thread1.start();
String future=futureTask.get();
System.out.println(Thread.currentThread().getName() + future);
}
4.线程池
ThreadPoolExecutor
是Java中一个灵活可定制的线程池类,它继承自AbstractExecutorService
类,并实现了ExecutorService
接口。通过ThreadPoolExecutor
类可以创建并管理线程池。
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName() + ">>>>>>这是实现了线程池");
});
threadPoolExecutor.shutdown();
}
创建了一个ThreadPoolExecutor
实例executor
,配置了核心线程数量为1,最大线程数量为3,线程空闲时间为60秒。同时,我们使用ArrayBlockingQueue
作为任务等待队列,它最大容量为100。
然后,通过execute()
方法提交任务给线程池执行。每个任务都是一个Lambda表达式,表示线程要执行的逻辑。
最后,我们调用shutdown()
方法关闭线程池。注意,这个方法将阻止新的任务提交,并且等待已经提交的任务完成执行。
ThreadPoolExecutor
提供了很多配置参数,可以根据实际需求定制线程池。你可以根据需要设置线程池的核心线程数、最大线程数、线程空闲时间等参数,以及选择不同的任务等待队列和拒绝策略。
通过使用ThreadPoolExecutor
,我们可以充分利用线程池来管理和执行线程,提高应用程序的并发性和资源利用率。