Java重拾系列(一)Java线程与线程池

    xiaoxiao2021-03-25  90

    Java中线程的几种使用方式:

    Runnable

    Runnable是一个接口,直接实现并在run方法中执行相应的任务。

    private class MyRunnableTask implements Runnable { @Override public void run() { // running my task int index = 0; while (index < 10) { System.out.println("I'm the task " + (++index)); } } } public void createRunnable() { MyRunnableTask runnableTask = new MyRunnableTask(); runnableTask.run(); }

    Thread 线程

    普通线程创建和启动的方式,创建Thread的实例时将Runnable对象传入其中,start()启动线程即可:

    public static void createThread() { Thread myThread = new Thread(new MyRunnableTask()); myThread.start(); }

    ThreadPool 线程池

    Executor

    public interface Executor { void execute(Runnable command); }

    Executor是用于代替显示的Thread创建,ExecutorService是拥有服务生命周期的Executor(例如shutDown / terminal等),ExecutorService需要通过Executors使用工厂方法来进行创建:

    public void createExecutor() { ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new MyRunnableTask()); }

    Executors

    Executor的工厂方法工具集,提供了各类ThreadPool的创建方法。注意创建的都是ExecutorService类型的对象。如下所示创建一个含有固定线程数的线程池,nThreads代表线程数量。更多方法可以查阅Executors.java文件。

    public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }

    ExecutorService

    public interface ExecutorService extends Executor

    ExecutorService继承自Executor,提供了更多的生命周期相关的方法,例如:

    void shutdown() <T> Future<T> submit(Callable<T> task) <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException省略…

    源码注释中提供了Usage Examples:

    class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorService pool; public NetworkService(int port, int poolSize) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize); } public void run() { // run the service try { for (;;) { pool.execute(new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } } class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // read and service request on socket } }

    以上代码可以看到,主要分为三个部分

    构造函数的初始化,建立了一个Socket对象,同时创建了一个固定线程数的线程池实例。内部类Handler实现了Runnable方法,通过Socket进行相应的服务请求与读取run()方法中循环执行了Handler的任务

    这就是线程池相应的使用。简单来说其实线程池只是由于Thread的种种不便应运而生的一种线程处理机制,没有想象的那么复杂与麻烦。并且相对的比起Thread的普通创建方式来说,线程池能够节省资源开销,更合理和优雅的管理线程的状态。

    Java通过Executor提供四种线程池:

    CachedThreadPool : 将为每个任务都创建一个线程

    FixedThreadPool : 预先执行代价高昂的线程分配,限制线程数量。优点是节省时间(创建线程需要开销)。直接从池中获取线程

    SingleThreadExecutor : 以FIFO的入队方式处理任务。在第一个任务处理完之前第二个任务出于等待状态

    ScheduledThreadPool : 能够延迟、周期性的执行任务,可以用于替换Timer

    线程池优点:

    在任何线程池中,现有的线程都可能被自动复用(线程池的优点之一就是资源复用)减少new Thread()的性能开销,每次使用线程都伴随Thread的创建和销毁开销,性能很差上面我们可以看到创建时能够指定线程的并发数量,也就是说,我们能够对线程进行有效的管理,普通创建线程只好待其自我执行、销毁,并且执行的时间点我们也无法得知,而这些事情通过线程池我们都能做到

    我们同样使用线程池来进行之前的循环打印,注意使用Executors和ExecutorService需要将其进行包的导入,两者都属于java.util.concurrent路径下:

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadDemo { private static class MyRunnableTask implements Runnable { @Override public void run() { int index = 0; while (index < 10) { System.out.println("I'm the task " + (++index)); } } } public static void createRunnable() { MyRunnableTask runnableTask = new MyRunnableTask(); runnableTask.run(); } public static void createThread() { Thread myThread = new Thread(new MyRunnableTask()); myThread.start(); } public static void createThreadPool() { ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new MyRunnableTask()); } public static void main(String[] args) { // createThread(); // createRunnable(); createThreadPool(); } }

    三种方式都可以打印出相应的结果:

    ➜ ~ javac ThreadDemo.java ➜ ~ java ThreadDemo I'm the task 1 I'm the task 2 I'm the task 3 I'm the task 4 I'm the task 5 I'm the task 6 I'm the task 7 I'm the task 8 I'm the task 9 I'm the task 10
    转载请注明原文地址: https://ju.6miu.com/read-17292.html

    最新回复(0)