ThreadPoolExecutor 线程池如何设置里面线程的最长执行时间?

时间:2021-12-05 08:21:32
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.io.*;

public class ThreadTest {
    private static int produceTaskSleepTime = 2;
    public static void main(String[] args) {
        //构造一个线程池
        ThreadPoolExecutor producerPool = new ThreadPoolExecutor(2, 6, 4,
                TimeUnit.SECONDS, new ArrayBlockingQueue(4),
                new ThreadPoolExecutor.CallerRunsPolicy());

        //每隔produceTaskSleepTime的时间向线程池派送一个任务。
        int i=1;
        while(true){
            try {
                Thread.sleep(produceTaskSleepTime);
                String task = "task@ " + i;
                System.out.println("put " + task);

                producerPool.execute(new ThreadPoolTask(task));

                i++;
                if(i>100) break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }



class ThreadPoolTask implements Runnable,Serializable{

    //JDK1.5中,每个实现Serializable接口的类都推荐声明这样的一个ID
    private static final long serialVersionUID = 0;
    private static int consumeTaskSleepTime = 200;
    private Object threadPoolTaskData;
    
    ThreadPoolTask(Object tasks){
        this.threadPoolTaskData = tasks;
    }

    //每个任务的执行过程,现在是什么都没做,除了print和sleep,:)
    public void run(){
        System.out.println("start .."+threadPoolTaskData);
        try {
            //便于观察现象,等待一段时间
            Thread.sleep(consumeTaskSleepTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        threadPoolTaskData = null;
    }
}  


ThreadPoolTask 如果因为某种原因一直停留在那里,这样导致线程池满了,而使后面的线程无法执行,基于这样的情况,如何能处理使那些占用很长时间的线程remove? 谢谢。急啊

3 个解决方案

#1


应该说你要去找原因为什么线程停留,是死锁就麻烦了。而不是把线程remove。
因为及时remove了,线程还是在内存中运行。当然你可以强制停止Thread.stop(),但是这样是不安全的,Java不建议作么做。
所以你还是要找出线程停留的BUG在那里。否则自己没有把握最好不要使用线程。

#2


ThreadPoolTask  就是调用javamail发送邮件

Session mailSession = Session.getInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
System.out.println("发送邮件成功!");

有些发送"发送邮件成功!"打不出来,则这个线程一直贮存在线程池里面了


核心部分
while (true) {

try {
lock.lock();
ob = (MMessage)queue.poll();
} finally {
lock.unlock();
}

try{
if(ob!=null){
    serverThreadPool.execute(new ServiceThread(ob));
    logger.debug("serverThreadPool.execute(new ServiceThread("+ob+"));");
}else{
Thread.sleep(produceTaskSleepTime);
}

}catch(Exception ex){
//e.printStackTrace();
logger.error("while thread",ex);
}
}


我在想会不会是Thread.sleep(produceTaskSleepTime);的问题
或者是
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
的时候由于某些原因会一直不释放?

#3


Session mailSession = Session.getInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
System.out.println("发送邮件成功!");
==================
那可以不一定会打印“发送邮件成功!”,因为你前面的语句都有可能抛出异常。
试试把可能发生异常的语句放到try语句中,打印语句放在final中。

#1


应该说你要去找原因为什么线程停留,是死锁就麻烦了。而不是把线程remove。
因为及时remove了,线程还是在内存中运行。当然你可以强制停止Thread.stop(),但是这样是不安全的,Java不建议作么做。
所以你还是要找出线程停留的BUG在那里。否则自己没有把握最好不要使用线程。

#2


ThreadPoolTask  就是调用javamail发送邮件

Session mailSession = Session.getInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
System.out.println("发送邮件成功!");

有些发送"发送邮件成功!"打不出来,则这个线程一直贮存在线程池里面了


核心部分
while (true) {

try {
lock.lock();
ob = (MMessage)queue.poll();
} finally {
lock.unlock();
}

try{
if(ob!=null){
    serverThreadPool.execute(new ServiceThread(ob));
    logger.debug("serverThreadPool.execute(new ServiceThread("+ob+"));");
}else{
Thread.sleep(produceTaskSleepTime);
}

}catch(Exception ex){
//e.printStackTrace();
logger.error("while thread",ex);
}
}


我在想会不会是Thread.sleep(produceTaskSleepTime);的问题
或者是
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
的时候由于某些原因会一直不释放?

#3


Session mailSession = Session.getInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect((String) props.get("mail.smtp.host"), username,password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
System.out.println("发送邮件成功!");
==================
那可以不一定会打印“发送邮件成功!”,因为你前面的语句都有可能抛出异常。
试试把可能发生异常的语句放到try语句中,打印语句放在final中。