Java中如何进行线程限制
假设我有 1000 个文件要读取,并且由于某些限制,我想并行读取最多 5 个文件。而且,一旦其中一个完成,我就想要一个新的开始。
我有一个主函数,它有文件列表,并且每当一个线程完成时我都会尝试更改计数器。但它不起作用!
有什么建议吗?
以下是main函数循环
for (final File filename : folder.listFiles()) {
Object lock1 = new Object();
new myThread(filename, lock1).start();
counter++;
while (counter > 5);
}
Let's say I have 1000 files to read and because of some limits, I want to read maximum 5 files in parallel. And, as soon as one of them is finished, I want a new one starts.
I have a main function who have the list of the files and I try changing a counter whenever one thread is finished. but it doesn't works!
Any suggestion?
The following is the main function loop
for (final File filename : folder.listFiles()) {
Object lock1 = new Object();
new myThread(filename, lock1).start();
counter++;
while (counter > 5);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
像这样生成线程并不是正确的方法。使用
ExecutorService
并将池指定为 5。将所有文件放入BlockingQueue
或其他线程安全集合之类的东西中,所有正在执行的文件都可以poll() 随意。
Spawning threads like this is not the way to go. Use an
ExecutorService
and specify the pool to be 5. Put all the files in something like aBlockingQueue
or another thread-safe collection and all the executing ones can justpoll()
it at will.您可以使用 ExecutorService 作为线程池和队列。
You can use an ExecutorService as a thread pool AND a queue.
凯拉的回答中的方法是正确的。使用 Java 类库提供的执行器类,而不是从头开始自己实现线程池(很糟糕)。
但我认为讨论您问题中的代码以及为什么它不起作用可能会有用。 (我已经尽力填写了您遗漏的一些部分...)
好吧,那么这有什么问题呢?为什么不起作用?
第一个问题是,在
main
中,您正在读取和写入counter
而不进行任何同步。我假设它也由工作线程更新 - 否则代码没有任何意义。因此,这意味着主线程很可能看不到子线程所做的更新的结果。换句话说,while (counter > 5);
可能是一个无限循环。 (事实上,这很有可能。JIT 编译器可以生成这样的代码,其中counter > 5
只是测试在前面的counter++;
语句。第二个问题是您的
while (counter > 5);
循环非常浪费资源。 ..并且它可能会执行数十亿次第二...全力运行一个处理器(核心) 如果您打算使用低级原语实现此类内容,则应该使用 Java 的Object.wait() 和
Object.notify()
方法;例如主线程等待,每个工作线程通知。The approach in Kylar's answer is the correct one. Use the executor classes provided by the Java class libraries rather than implementing thread pooling yourself from scratch (badly).
But I thought it might be useful to discuss the code in your question and why it doesn't work. (I've filled in some of the parts that you left out as best I can ...)
OK, so what is wrong with this? Why doesn't it work?
Well the first problem is that in
main
you are reading and writingcounter
without doing any synchronization. I assume that it is also being updated by the worker threads - the code makes no sense otherwise. So that means that there is a good chance that the main threads won't see the result of the updates made by the child threads. In other words,while (counter > 5);
could be an infinite loop. (In fact, this is pretty likely. The JIT compiler is allowed to generate code in which thecounter > 5
simply tests the value ofcounter
left in a register after the previouscounter++;
statement.The second problem is that your
while (counter > 5);
loop is incredibly wasteful of resources. You are telling the JVM to poll a variable ... and it will do this potentially BILLIONS of times a second ... running one processor (core) flat out. You shouldn't do that. If you are going to implement this kind of stuff using low-level primitives, you should use Java'sObject.wait()
andObject.notify()
methods; e.g. the main thread waits, and each worker thread notifies.无论您使用什么方法来创建新线程,递增全局计数器,在线程创建周围添加条件语句,如果达到限制,则不要创建新线程,也许将文件推送到队列(一个列表) ?),然后您可以在创建线程后添加另一个条件语句,如果队列中有项目,则首先处理这些项目。
Whatever method you are using to create a new Thread, increment a global counter, add a conditional statement around the thread creation that if the limit has been reached then don't create a new thread, maybe push the files onto a queue (a list?) and then you could add another conditional statement, after a thread is created, if there are items in the queue, to process those items first.
我们也可以使用信号量类。
因此 Semaphore 类将限制代码块上一次执行的线程数量。它有像 aquire()、release() 这样的方法来获取和释放锁这种机制
we can Semaphore class as well.
so Semaphore class will limit the number of threads executing at a time on block of code. It has methods like aquire(), release() to acquire and release the lock kind of mechanism