liuchangjie0112
javaboy_liuchj
采纳率25%
2019-05-29 14:59

线程池执行任务如何实现?

10
已采纳

要求调用尽可能多的线程执行入队列和出队列任务,希望线程名是不同的

package com.thread;

/**

  • @author liuchj
  • @version 1.0
  • @className MyThreadTest
  • @description //TODO
  • @date 2019/5/29 **/

import java.util.Queue;
import java.util.concurrent.*;

public class MyThreadTest {

public static void main(String[] args) {
    MyThreadTest mtt = new MyThreadTest();
    mtt.beginExe();
}


public void beginExe() {
    //线程池方式
    ExecutorService executor = new ThreadPoolExecutor(5, 5,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());
    executor.submit(new MyThreadTest.InnerThread());
}

/**
 * 线程:执行入队列、出队列任务的线程
 */
public class InnerThread implements Runnable {

    /**
     * 线程安全的队列
     */
    final Queue<String> queue = new ConcurrentLinkedQueue<String>();

    @Override
    public void run() {
        //入队列
        for (int i = 0; i < 9; i++) {
            queue.add("task" + i + "" + i);
        }

        //出队列
        while (queue.size() > 0) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String value = queue.poll();
            if (value != "" && null != value) {
                System.out.println(Thread.currentThread().getName() + "----- " + value);
            }
        }
    }

}

}

我要的效果不是这样的,如下创建线程的话,
InnerThread innerThread1 = new InnerThread();
InnerThread innerThread2 = new InnerThread();

    executor.submit(innerThread1);
    executor.submit(innerThread2);

结果:
pool-1-thread-2----- task00
pool-1-thread-1----- task00
pool-1-thread-2----- task11
pool-1-thread-1----- task11
pool-1-thread-2----- task22
pool-1-thread-1----- task22
pool-1-thread-1----- task33
pool-1-thread-2----- task33
pool-1-thread-2----- task44
pool-1-thread-1----- task44
pool-1-thread-2----- task55
pool-1-thread-1----- task55
pool-1-thread-2----- task66
pool-1-thread-1----- task66
pool-1-thread-2----- task77
pool-1-thread-1----- task77
pool-1-thread-2----- task88
pool-1-thread-1----- task88

,我要的不是上面这种效果,我想实现的类似结果如下:
Thread-2------------ task00
Thread-0------------ task22
Thread-4------------ task11
Thread-3------------ task33
Thread-1------------ task44
Thread-1------------ task55
Thread-3------------ task66
Thread-2------------ task77
Thread-0------------ task88

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • liuchangjie0112 javaboy_liuchj 2年前

    通过别的方式已经获取了答案,现在copy到此处,不过还是要感谢上面回答问题的小伙伴,虽然你的答案不是我想要的
    代码:

    package com.thread;
    /**
     * @author liuchj
     * @version 1.0
     * @className MyThreadTest
     * @description //TODO
     * @date 2019/5/29
     **/
    
    import java.util.Queue;
    import java.util.concurrent.*;
    
    public class ThreadPoolTask {
        /**
         * 线程安全的队列
         */
        static  Queue<String> queue = new ConcurrentLinkedQueue<String>();
    
        static {
            //入队列
            for (int i = 0; i < 9; i++) {
                queue.add("task-" + i );
            }
        }
    
        public static void main(String[] args) {
            //线程池方式
            ExecutorService executor = new ThreadPoolExecutor(5, 5,
                    10L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>());
    
            for (int i = 0; i < queue.size(); i++) {
                //提交任务
                InnerThread innerThread = new InnerThread();
                executor.submit(innerThread);
            }
            //关闭线程池中所有线程
            executor.shutdown();
           }
        }
    
        /**
         * 线程:执行出队列任务的线程
         */
         class InnerThread implements Runnable {
    
            @Override
            public void run() {            
                while (ThreadPoolTask.queue.size() > 0) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String value = ThreadPoolTask.queue.poll();
                    if (value != "" && null != value) {
                        System.out.println("线程"+Thread.currentThread().getName() + " 执行了task: " + value);
                    }
                }
            }
        }
    

    执行结果如下:

    线程pool-1-thread-3 执行了task: task-1
    线程pool-1-thread-1 执行了task: task-0
    线程pool-1-thread-5 执行了task: task-2
    线程pool-1-thread-4 执行了task: task-3
    线程pool-1-thread-2 执行了task: task-4
    线程pool-1-thread-1 执行了task: task-5
    线程pool-1-thread-5 执行了task: task-6
    线程pool-1-thread-3 执行了task: task-7
    线程pool-1-thread-4 执行了task: task-8
    

    结合上面小伙伴回答的,我总结后整理如下

    package com.thread;
    
    /**
     * @author liuchj
     * @version 1.0
     * @className MyThreadTest
     * @description //TODO
     * @date 2019/5/29
     **/
    
    import java.util.Queue;
    import java.util.concurrent.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class ThreadPoolTask {
    
        /**
         * 线程安全的队列
         */
        static  Queue<String> queue = new ConcurrentLinkedQueue<String>();
    
        static {
            //入队列
            for (int i = 0; i < 9; i++) {
                queue.add("task-" + i );
            }
        }
    
        public static void main(String[] args) {
            MyThreadFactory threadFactory = new MyThreadFactory();
            //线程池方式
            ExecutorService executor = new ThreadPoolExecutor(5, 5,
                    10L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>(),threadFactory);
    
            for (int i = 0; i < queue.size(); i++) {
                //提交任务
                InnerThread innerThread = new InnerThread();
                executor.submit(innerThread);
            }
            //关闭线程池中所有线程
            executor.shutdown();
           }
        }
    
        /**
         * 线程:执行出队列任务的线程
         */
         class InnerThread implements Runnable {
    
            @Override
            public void run() {
    
                //出队列
                while (ThreadPoolTask.queue.size() > 0) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String value = ThreadPoolTask.queue.poll();
                    if (value != "" && null != value) {
                        System.out.println("线程"+Thread.currentThread().getName() + " 执行了task: " + value);
                    }
                }
            }
        }
    
    class MyThreadFactory implements ThreadFactory{
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix ;
    
        public MyThreadFactory(){
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
    
            namePrefix = "Thread-";
        }
    
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            return t;
        }
    }
    
    

    执行结果:

    线程Thread-4 执行了task: task-1
    线程Thread-2 执行了task: task-0
    线程Thread-1 执行了task: task-3
    线程Thread-5 执行了task: task-2
    线程Thread-3 执行了task: task-4
    线程Thread-4 执行了task: task-5
    线程Thread-3 执行了task: task-6
    线程Thread-5 执行了task: task-7
    线程Thread-1 执行了task: task-8
    

    再次感谢小伙伴回答!

    点赞 评论 复制链接分享
  • wojiushiwo945you 毕小宝 2年前

    pool-1-thread-1 这个名称是线程池对象默认的,如果需要改变,则应该提供一个 ThreadFactory 的类实现作为参数传入:

    ThreadFactory threadFactory = new MyThreadFactory();
            // 线程池方式
            ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(),threadFactory );
    
    

    自定义的线程工厂类:

    public class MyThreadFactory implements ThreadFactory{
            private final ThreadGroup group;
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            private final String namePrefix ;
    
            public MyThreadFactory(){
                SecurityManager s = System.getSecurityManager();
                group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
    
                namePrefix = "Thread-";
            }
    
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(group, r,
                        namePrefix + threadNumber.getAndIncrement(),
                        0);
                return t;
            }
        }
    

    运行结果:
    图片说明

    分享一个小技巧:这里写的这个线程工厂,是从 Executors 类里面扒出来的,这里面有默认的工程实现 DefaultThreadFactory 它的工作线程命名规则是默认的 pool-1-thread 前缀的,我们可以定制线程名称的。

    点赞 1 评论 复制链接分享

相关推荐