要求调用尽可能多的线程执行入队列和出队列任务,希望线程名是不同的
package com.thread;
/**
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
通过别的方式已经获取了答案,现在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
再次感谢小伙伴回答!
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 前缀的,我们可以定制线程名称的。