线程池实现——我做对了吗?
thread pool implementation - am i doing it right?
我是多线程新手。
我很难理解我的实现有什么问题,以及为什么我看到的每个实现都使用同步块和通知。
运行 看起来不错,所以我不能指出到底哪里不好,但我假设有一些我没有遵循的多线程原则。
这是代码:
public class Threads {
static Queue<MyThread> queue = new LinkedList<>();
static Thread[] threadsArr = new Thread[10];
public static void main(String[] args) throws InterruptedException {
Threads t = new Threads();
t.startArr();
t.startProcess();
}
void startArr(){
for (int i=0;i<10;i++){
threadsArr[i] = new Thread(new MyThread(i));
}
}
void startProcess(){
for (int i=0;i<100;i++){
queue.add(new MyThread(i));
}
for (int i=0;i<100;i++){
int insertPlace = 0;
boolean isFull = true;
while (isFull){
for (int j=0;j<10;j++){
if (!threadsArr[j].isAlive()){
insertPlace = j;
isFull = false;
}
}
}
threadsArr[insertPlace] = new Thread(new MyThread(i));
threadsArr[insertPlace].start();
}
}
}
和 MyThread class:
public class MyThread implements Runnable {
int threadNumber;
public MyThread(int threadNumber){
this.threadNumber = threadNumber;
}
@Override
public void run() {
System.out.println(threadNumber + " started.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(threadNumber + " finished.");
}
}
谢谢。
我认为主要问题是您错过了 "ThreadPoolExecutor" 的角色。基本上,使用您的 class 的用户希望能够调用 "execute(Runnable run)" 方法,知道您的线程 class 将处理允许创建的进程中的执行。
您应该修改 class 的 API 并提供这种方法(例如参见真正的 ThreadPoolExecutor http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)。
其次,如果您正在接受面试培训,请尝试编写更简洁、更灵活的代码,不要在 class 周围使用像“10”这样的常量。这应该是你的 class 的用户提供的一个属性(在构造函数中),指定他想一次允许多少个线程(再次查看真正的 ThreadPoolExecutor)。
最后,我不是实施 ThreadPoolExecutors 的专家,但您可以考虑使用 BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html),它支持 "operations that wait for the queue to become non-empty when retrieving an element"。这对于等待线程可用而不是自己完成可能很有用。但我想还有更好的答案。
祝你好运,
马蒂亚斯
我是多线程新手。 我很难理解我的实现有什么问题,以及为什么我看到的每个实现都使用同步块和通知。 运行 看起来不错,所以我不能指出到底哪里不好,但我假设有一些我没有遵循的多线程原则。
这是代码:
public class Threads {
static Queue<MyThread> queue = new LinkedList<>();
static Thread[] threadsArr = new Thread[10];
public static void main(String[] args) throws InterruptedException {
Threads t = new Threads();
t.startArr();
t.startProcess();
}
void startArr(){
for (int i=0;i<10;i++){
threadsArr[i] = new Thread(new MyThread(i));
}
}
void startProcess(){
for (int i=0;i<100;i++){
queue.add(new MyThread(i));
}
for (int i=0;i<100;i++){
int insertPlace = 0;
boolean isFull = true;
while (isFull){
for (int j=0;j<10;j++){
if (!threadsArr[j].isAlive()){
insertPlace = j;
isFull = false;
}
}
}
threadsArr[insertPlace] = new Thread(new MyThread(i));
threadsArr[insertPlace].start();
}
}
}
和 MyThread class:
public class MyThread implements Runnable {
int threadNumber;
public MyThread(int threadNumber){
this.threadNumber = threadNumber;
}
@Override
public void run() {
System.out.println(threadNumber + " started.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(threadNumber + " finished.");
}
}
谢谢。
我认为主要问题是您错过了 "ThreadPoolExecutor" 的角色。基本上,使用您的 class 的用户希望能够调用 "execute(Runnable run)" 方法,知道您的线程 class 将处理允许创建的进程中的执行。 您应该修改 class 的 API 并提供这种方法(例如参见真正的 ThreadPoolExecutor http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)。
其次,如果您正在接受面试培训,请尝试编写更简洁、更灵活的代码,不要在 class 周围使用像“10”这样的常量。这应该是你的 class 的用户提供的一个属性(在构造函数中),指定他想一次允许多少个线程(再次查看真正的 ThreadPoolExecutor)。
最后,我不是实施 ThreadPoolExecutors 的专家,但您可以考虑使用 BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html),它支持 "operations that wait for the queue to become non-empty when retrieving an element"。这对于等待线程可用而不是自己完成可能很有用。但我想还有更好的答案。
祝你好运,
马蒂亚斯