Java线程池的使用实例

这篇文章主要讲解了“Java线程池的使用实例”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java线程池的使用实例”吧!

10年积累的网站设计、成都网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有三山免费网站建设让你可以放心的选择与我们合作。

第一种:创建一个定长的线程池,控制线程最大并发数,超出的会在队列中等待。

TestThreadPool.java

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();    //获取开始时间
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);//设置线程池的最大线程数
        for (int i = 0; i < 10; i++) {
            final int index = i;//一般多线程并发都用final
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(index + "  " + Thread.currentThread().getName());
                }
            });
        }
        long endTime = System.currentTimeMillis();    //获取结束时间
        System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
    }
}

输出结果:        Java线程池的使用实例 (当然输出结果不是固定的,不过线程数一定不会超过5个)

可以看到 Thread.currentThread().getName() 拿到的name只有5种,说明最大线程数控制在 5 个

工作队列用了LinkedBlockingQueue ,无界队列,当任务多而线程数少时,任务会存在队列里,容易内存溢出。

第二种:创建一个可缓存的线程池,可以灵活回收空闲线程,若无可回收,则新建线程。

TestThreadPool1.java

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestThreadPool1 {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10000; i++) {
            final int index = i;
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(index + "  " + Thread.currentThread().getName());
                }
            });
        }
    }
}

输出结果的 Thread.currentThread().getName() 拿到的name有一两千种(当然不同环境和配置的机器的结果最大线程数是不同的)

工作队列使用SynchronousQueue同步队列。会根据任务数创建线程,数量太大容易导致cpu使用率100%  99%

第三种:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

TestThreadPool2.java

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestThreadPool2 {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10000; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                public void run() {
                    System.out.println(index + "  " + Thread.currentThread().getName());
                }
            });
        }
    }
}

输出结果:无论循环100次还是100000次,输出结果Thread.currentThread().getName()的值都会是

                   pool-1-thread-1

Java线程池的使用实例

第四种:创建一个定长线程池,可以延时或定时周期性地执行任务。

TestThreadPool3.java

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool3 {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                public void run() {
                    try {
                        while(true) {
                            System.out.println(index + "  " + Thread.currentThread().getName());
                            Thread.sleep(10 * 1000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

输出结果:每隔10s就会输出10行结果
                   Java线程池的使用实例

**使用 ScheduledExecutorService 的 scheduleAtFixedRate方法可以设置延时和执行间隔

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
Creates and executes a periodic action that becomes enabled first after the given initial delay,
and subsequently with the given period; that is executions will commence after initialDelay 
then initialDelay+period, then initialDelay + 2 * period, and so on.

意思是创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。

TestThreadPool4.java

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TestThreadPool4 {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        System.out.println(System.currentTimeMillis());
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println(System.currentTimeMillis());
            }
        }, 5, 10, TimeUnit.SECONDS);
    }
}

从输出结果可以看出,延时5s后每隔10s会输出一次当前时间。

**使用ScheduledExecutorService的schedule可以设置首次执行延时

schedule(Runnable command, long delay, TimeUnit unit)
Creates and executes a one-shot action that becomes enabled after the given delay.

创建并执行在给定延迟后启用的一次性操作。

TestThreadPool5.java

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TestThreadPool5 {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            scheduledThreadPool.schedule(new Runnable() {
                public void run() {
                    System.out.println(index + "  " + Thread.currentThread().getName());
                }
            }, 3, TimeUnit.SECONDS);
        }
    }
}

输出结果:运行3s后会输出10行结果,而不会每隔3s输出一行。

感谢各位的阅读,以上就是“Java线程池的使用实例”的内容了,经过本文的学习后,相信大家对Java线程池的使用实例这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


分享名称:Java线程池的使用实例
本文路径:http://myzitong.com/article/gsojds.html