精华内容
下载资源
问答
  • JAVA 查看线程池状态

    千次阅读 2020-04-02 13:55:44
    /** * 线程池状态查看 */ public class TestThread { private static ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.Builder().namingPattern("schedule-pool-...
    
    
    //<!-- 需要依赖 pool 对象池 -->
    //<dependency>
    //<groupId>org.apache.commons</groupId>
    //<artifactId>commons-pool2</artifactId>
    //</dependency>
    
    import org.apache.commons.lang3.concurrent.BasicThreadFactory;
    
    import java.util.TimerTask;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    
    /**
     * 线程池状态查看
     */
    public class TestThread {
        private static ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
    
        public static void main(String[] args) {
            executor.schedule(newTask("aaa"), 10, TimeUnit.MILLISECONDS);
            executor.schedule(newTask("bbb"), 10, TimeUnit.MILLISECONDS);
            executor.schedule(newTask("ccc"), 10, TimeUnit.MILLISECONDS);
            executor.schedule(newTask("一秒"), 1000, TimeUnit.MILLISECONDS);
            executor.schedule(newTask("5秒"), 5000, TimeUnit.MILLISECONDS);
            executor.schedule(badTask(), 10, TimeUnit.MILLISECONDS);
    
    
            while (getPoolInfo((ThreadPoolExecutor) executor) > 0) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private static int getPoolInfo(ThreadPoolExecutor tpe) {
            System.out.println();
            int queueSize = tpe.getQueue().size();
            System.out.println("当前排队线程数:" + queueSize);
    
            int activeCount = tpe.getActiveCount();
            System.out.println("当前活动线程数:" + activeCount);
    
            long completedTaskCount = tpe.getCompletedTaskCount();
            System.out.println("执行完成线程数:" + completedTaskCount);
    
            long taskCount = tpe.getTaskCount();
            System.out.println("总线程数:" + taskCount);
    
            //线程池中当前线程的数量,为0时意味着没有任何线程,线程池会终止,此值不会超过MaximumPoolSize
            System.out.println("当前线程的数量:" + tpe.getPoolSize());
    
            //线程池的初始线程数量(当没有任务提交,或提交任务数小于此值值,实际并不会产生那么多线程数)
            System.out.println("线程池的初始线程数量:" + tpe.getCorePoolSize());
    
            //线程池可允许最大的线程数
            System.out.println("线程池可允许最大的线程数" + tpe.getMaximumPoolSize());
            tpe.getLargestPoolSize();
    
            return queueSize;
        }
    
        private static TimerTask newTask(String str) {
            return new TimerTask() {
                @Override
                public void run() {
                    System.err.println("线程:" + Thread.currentThread().getName() + " = " + str);
                }
            };
        }
    
        private static TimerTask badTask() {
            return new TimerTask() {
                @Override
                public void run() {
                    System.err.println("坏的线程:" + Thread.currentThread().getName());
                    //对于异常一定要捕获,否则没有任何提示
                    try {
                        int i = 1 / 0;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
        }
    }
    

     

    展开全文
  • 主要介绍了Java判断线程池线程是否执行完毕,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了Java 判断线程池所有任务是否执行完毕的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 主要介绍了java 定时器线程池(ScheduledThreadPoolExecutor),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要介绍了JAVA 自定义线程池的最大线程数设置方法,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
  • Java线程池使用说明

    2018-02-24 11:12:14
    Java线程池使用说明Java线程池使用说明Java线程池使用说明
  • 自定义实现Java线程池

    2018-09-22 20:59:38
    自定义实现Java线程池,学习大师设计思想,瞻仰大神笔法
  • java线程池封装

    2018-05-24 16:48:03
    java线程池封装,可自定义线程优先级,使用方便。。。
  • java 四种线程池实例

    2018-06-06 16:01:55
    执行一个异步任务你还只是如下new Thread吗?是不是太low 了一点? 我这里有四种线程池的案例轻松让你理解和使用线程池
  • 本文旨在使用Java语言编写一个通用的线程池。当需要使用线程池处理事务时,只需按照指定规范封装好事务处理对象,然后用已有的线程池对象去自动选择空 闲线程自动调用事务处理对象即可。并实现线程池的动态修改...
  • 主要介绍了java线程池框架及线程池的原理的相关资料,需要的朋友可以参考下
  • 主要为大家详细介绍了Java手写线程池的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Java线程池运行状态监控实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了Java 线程池详解及创建简单实例的相关资料,需要的朋友可以参考下
  • 下面小编就为大家带来一篇浅谈java常用的几种线程池比较。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了Java线程池FutureTask实现原理详解,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
  • Java 确定线程池中工作线程数的大小

    万次阅读 2018-09-12 16:20:17
    之前来看的《java并发编程实战》,里面有讲,要正确地设置线程池的大小,你必须估算出任务的等待时间和计算时间的比值,这种估算不会很精确。也可以使用另一种方式,就是:在某一个基准负载下,分别设置不同大小的...

    以问答形式展开,会更有针对性:
    1、工作线程是不是越多越好?

         不是。a、服务器cpu核数有限,所以同时并发或者并行的线程数是有限的,所以1核cpu设置1000个线程是没有意义的。

     b、线程切换也是有开销的。频繁切换线程会使性能降低。

    2、调用sleep()函数的时候,县城是否会占用着CPU?

        不占用,sleep()函数切换时会把cpu让出来。accept()阻塞和recv()阻塞时也会让出cpu。

    3、cpu单核,做多线程有用吗?

        多线程并发是有用的,但是起的线程数量太多会造成线程频繁上下文切换,开销大,性能衰弱。

        好了,回到我们主题,我们希望确定线程池中核心线程数的大小。之前来看的《java并发编程实战》,里面有讲,要正确地设置线程池的大小,你必须估算出任务的等待时间和计算时间的比值,这种估算不会很精确。也可以使用另一种方式,就是:在某一个基准负载下,分别设置不同大小的线程池来运行应用程序,并观察cpu利用率的水平。

        先将按公式计算线程池的大小,公式如下:

        对于,线程池中线程的个数,在《java虚拟机并发编程》中会定义如下:

        线程数=cpu可用核心数/(1-阻塞系数),其中阻塞系数的取值在[0,1]之间。计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。一般,我们让线程执行的任务是比较复杂的,不会是单一的计算密集型任务,或者单一的IO密集型任务,通常会夹杂着。那么就需要我们去计算阻塞系数了。阻塞系数的定义就是执行该任务阻塞的时间与(阻塞时间+计算时间)的比值,也就是w/(w+c)。

         两本书中对于可用线程数的定义公式是不一样的,但是到底原理是不是一样的呢?我们用假设法验证一下:假设两个公式计算的线程数是一样的,也就是说,得到如下等式:

    也就是说,两本书上的公式原理是一样的,那么我们就可以方便使用了,这边可以考虑使用<java并发编程实战>的公式,因为他考虑到cpu使用率。也就是说我们在实际使用时,可以根据以上的公式计算出,服务器上能够长期存在的线程个数。可以设置CPU的使用率,cpu的可用核数可以通过java中的以下方法获得:

    Runtime.getRuntime().availableProcessors()

    该方法的注释可以理解用处:

    /**
     * Returns the number of processors available to the Java virtual machine.
     *
     * <p> This value may change during a particular invocation of the virtual
     * machine.  Applications that are sensitive to the number of available
     * processors should therefore occasionally poll this property and adjust
     * their resource usage appropriately. </p>
     *
     * @return  the maximum number of processors available to the virtual
     *          machine; never smaller than one
     * @since 1.4
     */
    public native int availableProcessors();
    /*
    返回Java虚拟机可用的处理器数。
         *
          * <p>在特定的虚拟机调用期间,此值可能会更改。 因此,对可用处理器数量敏感的应用程序应偶尔轮询此属性并适当调整其资源使用情况。</ p>
         *
          * @return虚拟机可用的最大处理器数量; 永远不会小于一个
    
    
    所以在性能敏感的应用中,创建线程池时,最好根据这个值来动态设定线程池的核心线程数。
    */

         那么w/c怎么计算呢?可以将你的需要执行的任务量化,你需要确定哪些步骤是IO操作,哪些步骤的计算操作,然后跑一次,来确定执行这个任务耗费在IO多少时间,耗费在计算上多少时间,两者的比值就是W/C。在知道cpu可用核心数,预期的cpu使用率,和W/C这些值之后就可计算出工作线程数的大小了。

        这边介绍一下一般经验:

        IO密集型:如果存在ID,那么w/c>1,阻塞耗时一般都会比计算耗时的很多倍。如果不想做以上的计算,那么可以设置工作线程数为2倍cpu可用线程数。IO包括:数据库交互,文件上传下载,网络传输等

        计算密集型:工作线程数就是cpu可用核数。这样比较保险

     

     

     

     

    展开全文
  • Java 自己实现线程池

    2014-12-13 22:45:37
    Java开发,Android开发,自己实现线程池,明白线程池的实现机制
  • NULL 博文链接:https://yulincqupt.iteye.com/blog/1673919
  • 深入理解Java线程池

    2020-12-22 17:12:28
    在前面的文章中,我们...我们来详细讲解一下Java线程池,首先我们从核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,后讨论了一下如何合理配置线程池的大小。  以下是
  • 主要为大家详细介绍了java线程池实现批量下载文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Java手动配置线程池过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Java自定义线程池

    千次阅读 2020-06-29 20:48:54
    学习自定义线程池之前大家应该先学习设计模式-享元模式 下面这张图就是自定义线程池原理: ThreadPool类就是我们的线程池; BlockQuene类是我们定义的阻塞队列,当线程池满了,我们把来的任务先放到阻塞队列中; ...

    学习自定义线程池之前大家应该先学习设计模式-享元模式

    • 下面这张图就是自定义线程池原理:
    1. ThreadPool类就是我们的线程池;
    2. BlockQuene类是我们定义的阻塞队列,当线程池满了,我们把来的任务先放到阻塞队列中;
    3. main就是我们客户也就是生产者,那线程池就是消费者;
      在这里插入图片描述
      在这里插入图片描述

    ThreadPool类

    ThreadPool里面有内部类Worker,它是线程池中装任务的容器,当任务来了就放到这个里面。
    线程池当然还要维护线程池的最大任务个数,当线程池中有空的worker那么就从阻塞队列blockqueue中拿取,当线程池满了,来的任务就放入阻塞队列。
    excuteTask方法中当线程池已经满了,那么可以选择这时是放入阻塞队列中,当时else中我们有注释,我们利用策略模式思想,可以选择当阻塞队列满了,我们选择怎么办,可以抛出异常,或者直接用我们写好的put死等,或者超时等待tryput方法。

    class ThreadPool{
        //核心线程数
        private int coreSize;
        //获取任务的超时时间
        private long timeout;
    
        private TimeUnit unit;
        //任务队列
        private BlockQuene<Runnable> taskqueue;
        //线程集合
        private HashSet<Worker> workers=new HashSet<>();
    
        private RejectPolicy<Runnable> rejectPolicy;
    
        public ThreadPool(int coreSize, long timeout, TimeUnit unit,int queueCapcity,RejectPolicy<Runnable> rejectPolicy) {
            this.coreSize = coreSize;
            this.timeout = timeout;
            this.unit = unit;
            this.taskqueue=new BlockQuene<>(queueCapcity);
            this.rejectPolicy=rejectPolicy;
        }
    
        //执行任务
        public void excuteTask(Runnable task){
            //来一个任务,如果不超过线程池的核心线程数,则加入到线程池进行工作,如果此时池中线程数超过核心线程数,则加入阻塞等待队列。
            ReentrantLock lock=new ReentrantLock();
            lock.lock();
            try{
                if (workers.size() < coreSize){
                    System.out.println("增加任务");
                    Worker worker=new Worker(task);
                    workers.add(worker);
                    worker.start();
                }else {
                    System.out.println("加入任务队列一个");
                    //taskqueue.put(task);
                    //当我们的阻塞队列满了,这时我们能够采取的措施
                    //1.死等wait,无参添加队列方法的实现
                    //2.添加入队列方法,加上时间参数,超时无法添加则放弃添加
                    //3.让调用者放弃执行
                    //4.让调用者抛出异常
                    //5.让调用者自己执行任务
                    //各种选择
                    taskqueue.tryput(rejectPolicy,task);//超时等待方法
                }
            }finally {
                lock.unlock();
            }
        }
    
    
        class Worker extends Thread{
            private Runnable task;
    
            public Worker(Runnable task) {
                this.task = task;
            }
    
            @Override
            public void run() {
                //while保证worker能不断的不停执行
                //当task里面有任务则执行,没有任务则从阻塞队列里面获取
                //执行完worker里的任务则讲task重新置为null为了下一次放任务
                while (task != null || (task = taskqueue.tack())!=null){
                    try{
                        task.run();
                    }finally {
                        task=null;
                    }
                }
                synchronized (this){
                    workers.remove(this);
                }
            }
        }
    }
    

    BlockQuene类

    阻塞队列,当生产者main提供任务,线程池已经满了,那么就先将任务放入阻塞队列中,当线程池有空位,那么从阻塞队列中拿任务。

    class BlockQuene<T>{//阻塞队列
        //锁
        private ReentrantLock lock =new ReentrantLock();
        //任务队列
        private Deque<T> queue=new ArrayDeque<>();
        //生产者状态main
        private Condition fullwaitset=lock.newCondition();
        //消费者状态threadpool
        private Condition emptywaitset=lock.newCondition();
        //容量
        private int capacity;
    
        public BlockQuene(int capacity) {
            this.capacity = capacity;
        }
    
        //阻塞获取
        public T tack(){
            lock.lock();
            try {
                while (queue.isEmpty()){
                    try {
                        emptywaitset.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                T element=queue.removeFirst();
                fullwaitset.signal();//当阻塞队列挪走一个线程则唤醒满阻塞队列中的一个线程
                return element;
            }finally {
                lock.unlock();
            }
        }
        //超时获取方法,就是take的超时实现
        public T poll(long timeout, TimeUnit unit){
            lock.lock();
            try{
                long nanos=unit.toNanos(timeout);
                while (queue.isEmpty()){
                    try {
                        nanos=emptywaitset.awaitNanos(nanos);//返回的是剩余时间
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                T element=queue.removeFirst();
                fullwaitset.signal();//当阻塞队列挪走一个线程则唤醒满监控中的一个线程
                return element;
            } finally {
                lock.unlock();
            }
        }
    
    
    
        //阻塞添加,死等方法,阻塞队列满时就死等
        public void put(T element){
            lock.lock();
            try {
                while (queue.size() >= capacity){
                    try {
                        fullwaitset.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                queue.addLast(element);
                emptywaitset.signal();//当不为空则告诉消费者里有线程
            }finally {
                lock.unlock();
            }
        }
        //超时等待放入,阻塞队列满,则等待参数时间,参数时间不能放入放回flase
        public boolean put(T task,long timeout,TimeUnit unit){
            lock.lock();
            try {
                long nanos = unit.toNanos(timeout);
                while (queue.size() >= capacity){//超过了阻塞队列容量
                    if (nanos <= 0){//超时
                        return false;
                    }
                    try {
                        nanos= fullwaitset.awaitNanos(nanos);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                queue.addLast(task);
                emptywaitset.signal();
                return true;
            } finally {
                lock.unlock();
            }
        }
    
        //获取大小
        public int getCapacity(){
            lock.lock();
            try{
                return queue.size();
            }finally {
                lock.unlock();
            }
        }
    
        public void tryput(RejectPolicy rejectPolicy,T task) {
            lock.lock();
            try {
                if (queue.size()>=capacity){
                    rejectPolicy.reject(this,task);
                }else {
                    queue.addLast(task);
                    emptywaitset.signal();
                }
            } finally {
                lock.unlock();
            }
        }
    }
    

    用策略模式思想来实现当阻塞队列满时不同实现方法,这是策略接口

    interface RejectPolicy<T>{
        void reject(BlockQuene<T> quene,T task);
    }
    

    main

    public class TestPool1 {
        public static void main(String[] args) {
            ThreadPool threadPool=new ThreadPool(2,1000,TimeUnit.MILLISECONDS,10, ((quene, task) -> {
                quene.put(task);
                }
            ));
            for (int i = 0; i <5; i++) {
                threadPool.excuteTask(()->{
                    System.out.println("nihao");
                });
            }
        }
    }
    
    展开全文
  • java线程池处理多并发,所有进程执行完后再统一处理结果线程池配置类多线程并行demo 线程池配置类 import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation....
  • 通过剖析Java中线程池的原理,解读Java线程池源码,并给出线程池调用的示例,帮助理解线程池的基本原理。
  • 主要为大家详细介绍了基于java线程池读取单个SQL数据库表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • linux查看java进程|线程池信息

    万次阅读 2017-10-14 11:21:15
    1.根据端口号57638查看对应进程pid/name=1463/java  netstat -apn | grep 57638 tcp 0 0 ::ffff:172.20.5.10:57638 :::* LISTEN 1463/java tcp 0

    1.根据端口号57638查看对应进程pid/name=1463/java     

       netstat -apn | grep  57638  

    tcp        0      0 ::ffff:172.20.5.10:57638    :::*                        LISTEN      1463/java           
    tcp        0      0 ::ffff:172.20.5.10:57638    ::ffff:172.20.5.14:59204    ESTABLISHED 1463/java


    2. top 查看占用内存最多的几个进程

    ps aux | grep applicationName  查看对应applicationName的pid, 第二列表示pid 1463

    root      1463 12.5  2.3 5531468 3057636 ?     Sl   Oct12 315:22


    3. top  -p pid -H 查看进程pid对应的线程信息,这里每个线程映射对应到linux的一个进程PID

    top  -p 1463 -H

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                      
     1463 root      20   0 5401m 2.9g  39m S  0.0  2.3   0:00.00 java                                                                                          
     1464 root      20   0 5401m 2.9g  39m S  0.0  2.3   0:01.69 java


    4.  使用jstack查看对应线程的具体信息

    jstack pid | grep -A 10 hex(id)

    pid进程id,  -A 表示 取出对应行后,往后继续显示10行内容, 

    hex(id) 表示线程PID对应的十六进制数字,全部用小写字母表示,

    可以借助计算器 或其他工具进行转换, 用python 转换: python -c "print (hex(1464))"

    jstack 1463 | grep -A 10 `python -c "print (hex(1464))"`

    "main" #1 prio=5 os_prio=0 tid=0x00007f15ac01e800 nid=0x5b8 waiting on condition [0x00007f15b0a37000]
       java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000700016ba0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1465)
    at org.apache.spark.rpc.netty.Dispatcher.awaitTermination(Dispatcher.scala:180)
    at org.apache.spark.rpc.netty.NettyRpcEnv.awaitTermination(NettyRpcEnv.scala:273)
    at org.apache.spark.executor.CoarseGrainedExecutorBackend$$anonfun$run$1.apply$mcV$sp(CoarseGrainedExecutorBackend.scala:231)
    at org.apache.spark.deploy.SparkHadoopUtil$$anon$1.run(SparkHadoopUtil.scala:67)



    ref: http://blog.csdn.net/jiafu1115/article/details/7355628

    http://flysnowxf.iteye.com/blog/1162691

    https://www.zhihu.com/question/20238208

    http://blog.csdn.net/hanghangaidoudou/article/details/51488249


                                                                                             






    展开全文
  • 我们在使用线程池的时候,想知道当前线程池下创建了多少个线程,或者创建了多少个线程池数 可以通过下面的例子了解到: import java.util.concurrent.ExecutorService; import java.util.concurrent....
  • 主要介绍了Java并发之串行线程池实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
  • 主要给大家介绍了关于java线程池使用后到底要不要关闭的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 284,044
精华内容 113,617
关键字:

java查看线程池

java 订阅