1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00

* make sure core size is not limited to max thread pool size (seems to be a enforced limit now in JDK 8)

This commit is contained in:
Reinhard Pointner 2014-11-04 11:11:04 +00:00
parent fc70050ce3
commit 73c88dd365

View File

@ -1,7 +1,5 @@
package net.filebot.ui.sfv; package net.filebot.ui.sfv;
import static java.lang.Math.*; import static java.lang.Math.*;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
@ -17,21 +15,18 @@ import java.util.concurrent.atomic.AtomicInteger;
import net.filebot.util.DefaultThreadFactory; import net.filebot.util.DefaultThreadFactory;
class ChecksumComputationService { class ChecksumComputationService {
public static final String TASK_COUNT_PROPERTY = "taskCount"; public static final String TASK_COUNT_PROPERTY = "taskCount";
private final Set<ThreadPoolExecutor> executors = new HashSet<ThreadPoolExecutor>(4); private final Set<ThreadPoolExecutor> executors = new HashSet<ThreadPoolExecutor>(4);
private final AtomicInteger completedTaskCount = new AtomicInteger(0); private final AtomicInteger completedTaskCount = new AtomicInteger(0);
private final AtomicInteger totalTaskCount = new AtomicInteger(0); private final AtomicInteger totalTaskCount = new AtomicInteger(0);
public ExecutorService newExecutor() { public ExecutorService newExecutor() {
return new ChecksumComputationExecutor(); return new ChecksumComputationExecutor();
} }
public void reset() { public void reset() {
synchronized (executors) { synchronized (executors) {
@ -43,16 +38,15 @@ class ChecksumComputationService {
} }
} }
} }
totalTaskCount.set(0); totalTaskCount.set(0);
completedTaskCount.set(0); completedTaskCount.set(0);
executors.clear(); executors.clear();
} }
pcs.firePropertyChange(TASK_COUNT_PROPERTY, -1, getTaskCount()); pcs.firePropertyChange(TASK_COUNT_PROPERTY, -1, getTaskCount());
} }
/** /**
* Get the number of active executors that are associated with this {@link ChecksumComputationService}. * Get the number of active executors that are associated with this {@link ChecksumComputationService}.
@ -65,22 +59,18 @@ class ChecksumComputationService {
return executors.size(); return executors.size();
} }
} }
public int getTaskCount() { public int getTaskCount() {
return totalTaskCount.get() - completedTaskCount.get(); return totalTaskCount.get() - completedTaskCount.get();
} }
public int getTotalTaskCount() { public int getTotalTaskCount() {
return totalTaskCount.get(); return totalTaskCount.get();
} }
public int getCompletedTaskCount() { public int getCompletedTaskCount() {
return completedTaskCount.get(); return completedTaskCount.get();
} }
public void purge() { public void purge() {
synchronized (executors) { synchronized (executors) {
@ -89,13 +79,12 @@ class ChecksumComputationService {
} }
} }
} }
private class ChecksumComputationExecutor extends ThreadPoolExecutor { private class ChecksumComputationExecutor extends ThreadPoolExecutor {
public ChecksumComputationExecutor() { public ChecksumComputationExecutor() {
super(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DefaultThreadFactory("ChecksumComputationPool", Thread.MIN_PRIORITY)); super(1, Runtime.getRuntime().availableProcessors(), 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DefaultThreadFactory("ChecksumComputationPool", Thread.MIN_PRIORITY));
synchronized (executors) { synchronized (executors) {
if (executors.add(this) && executors.size() == 1) { if (executors.add(this) && executors.size() == 1) {
// first executor of a new session, reset counts // first executor of a new session, reset counts
@ -103,10 +92,9 @@ class ChecksumComputationService {
completedTaskCount.set(0); completedTaskCount.set(0);
} }
} }
prestartAllCoreThreads(); prestartAllCoreThreads();
} }
protected int getPreferredPoolSize() { protected int getPreferredPoolSize() {
// for a few files, use one thread // for a few files, use one thread
@ -114,67 +102,62 @@ class ChecksumComputationService {
// e.g 50 files ~ 1 thread, 200 files ~ 2 threads, 1000 files ~ 3 threads, 40000 files ~ 5 threads // e.g 50 files ~ 1 thread, 200 files ~ 2 threads, 1000 files ~ 3 threads, 40000 files ~ 5 threads
return max((int) log10(getQueue().size()), 1); return max((int) log10(getQueue().size()), 1);
} }
@Override @Override
public void execute(Runnable command) { public void execute(Runnable command) {
int preferredPoolSize = getPreferredPoolSize(); int preferredPoolSize = getPreferredPoolSize();
if (getCorePoolSize() < preferredPoolSize) { if (getCorePoolSize() < preferredPoolSize) {
setCorePoolSize(preferredPoolSize); setCorePoolSize(preferredPoolSize);
} }
synchronized (this) { synchronized (this) {
super.execute(command); super.execute(command);
} }
totalTaskCount.incrementAndGet(); totalTaskCount.incrementAndGet();
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() - 1, getTaskCount()); pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() - 1, getTaskCount());
} }
@Override @Override
public void purge() { public void purge() {
int delta = 0; int delta = 0;
synchronized (this) { synchronized (this) {
delta += getQueue().size(); delta += getQueue().size();
super.purge(); super.purge();
delta -= getQueue().size(); delta -= getQueue().size();
} }
if (delta > 0) { if (delta > 0) {
// subtract removed tasks from task count // subtract removed tasks from task count
totalTaskCount.addAndGet(-delta); totalTaskCount.addAndGet(-delta);
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + delta, getTaskCount()); pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + delta, getTaskCount());
} }
} }
@Override @Override
protected void afterExecute(Runnable r, Throwable t) { protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t); super.afterExecute(r, t);
if (isValid()) { if (isValid()) {
if (r instanceof Future && ((Future<?>) r).isCancelled()) { if (r instanceof Future && ((Future<?>) r).isCancelled()) {
totalTaskCount.decrementAndGet(); totalTaskCount.decrementAndGet();
} else { } else {
completedTaskCount.incrementAndGet(); completedTaskCount.incrementAndGet();
} }
pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + 1, getTaskCount()); pcs.firePropertyChange(TASK_COUNT_PROPERTY, getTaskCount() + 1, getTaskCount());
} }
} }
protected boolean isValid() { protected boolean isValid() {
synchronized (executors) { synchronized (executors) {
return executors.contains(this); return executors.contains(this);
} }
} }
@Override @Override
protected void terminated() { protected void terminated() {
@ -183,17 +166,15 @@ class ChecksumComputationService {
} }
} }
} }
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener listener) { public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener); pcs.addPropertyChangeListener(listener);
} }
public void removePropertyChangeListener(PropertyChangeListener listener) { public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener); pcs.removePropertyChangeListener(listener);
} }
} }