scheduleAtFixedRate 的并发 ScheduledThreadPoolExecutor 的 IllegalArgumentException
IllegalArgumentException of concurrent ScheduledThreadPoolExecutor for scheduleAtFixedRate
我正在 运行 在我的 Mac 上为 HotSpot JDK8 创建一个测试文件。我使用 IntelliJ IDEA 运行 这个 java 程序。
IntelliJ IDEA 2017.1.2
Build #IC-171.4249.39, built on April 25, 2017
JRE: 1.8.0_112-release-736-b16 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.12.5
我在 Runner.java
文件中设置 frequency
时出错。例如,如果我在下面的赋值中设置 25,5 来代替 50,我会得到错误。这是为什么?
int frequency = 50 * runSpecification.objectSize / runSpecification.allocationRatePerSecond; // 25 will fail and yield bug
Exception in thread "main" java.lang.IllegalArgumentException
at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:565)
at eu.plumbr.gc.Runner.run(Runner.java:30)
at eu.plumbr.gc.Runner.main(Runner.java:21)
Process finished with exit code 1
.
└── main
└── java
└── eu
└── plumbr
└── gc
├── Consumer.java
├── Producer.java
├── RunSpecification.java
└── Runner.java
5 directories, 4 files
Consumer.java
package eu.plumbr.gc;
import java.util.Deque;
public class Consumer implements Runnable{
private Deque<byte[]> deque;
public Consumer(Deque<byte[]> deque) {
this.deque = deque;
}
@Override
public void run() {
deque.poll();
}
}
Producer.java
package eu.plumbr.gc;
import java.util.Deque;
public class Producer implements Runnable {
private Deque<byte[]> deque;
private int objectSize;
public Producer(Deque<byte[]> deque, int objectSize) {
this.deque = deque;
this.objectSize = objectSize;
}
@Override
public void run() {
deque.add(new byte[objectSize]);
}
}
Runner.java
package eu.plumbr.gc;
import java.util.ArrayDeque;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Runner {
private RunSpecification runSpecification;
private ScheduledExecutorService executorService;
public Runner(RunSpecification runSpecification, ScheduledExecutorService executorService) {
this.runSpecification = runSpecification;
this.executorService = executorService;
}
public static void main(String[] args) throws InterruptedException {
Runner runner = new Runner(new RunSpecification(10 * 1024, 1024 * 500, 5), Executors.newScheduledThreadPool(2));
runner.run();
}
public void run() {
ArrayDeque<byte[]> deque = new ArrayDeque<byte[]>();
Producer producer = new Producer(deque, runSpecification.objectSize);
Consumer consumer = new Consumer(deque);
int frequency = 50 * runSpecification.objectSize / runSpecification.allocationRatePerSecond; // 25 will fail and yield bug
executorService.scheduleAtFixedRate(producer, 0, frequency, TimeUnit.MILLISECONDS);
executorService.scheduleAtFixedRate(consumer, 1000 * runSpecification.ttl, frequency, TimeUnit.MILLISECONDS);
}
}
RunSpecification.java
package eu.plumbr.gc;
public class RunSpecification {
public int objectSize;
public int allocationRatePerSecond;
public int ttl;
public RunSpecification(int objectSize, int allocationRatePerSecond, int ttl) {
this.objectSize = objectSize;
this.allocationRatePerSecond = allocationRatePerSecond;
this.ttl = ttl;
}
}
参考:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
如果您阅读 javadoc,您将会看到
IllegalArgumentException - 如果周期小于或等于零
不知道你的确切输入,但我会说
int frequency = 50 * runSpecification.objectSize /
runSpecification.allocationRatePerSecond;
frequency
大于 0,但使用 25 则不是
记住你在做整数除法,这可以通过
来验证
int objectSize = 10240;
int allocationRatePerSecond = 512000;
System.out.println(50 * objectSize / allocationRatePerSecond);
System.out.println(25 * objectSize / allocationRatePerSecond);
输出
1
0
根据'Scary Wombat'建议的解决方案,我进行了修改并消除了错误。即,IllegalArgumentException - 如果周期小于或等于零
初始代码:
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(this, 0, 1, TimeUnit.valueOf(DAYS));
更正后的代码:
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(this, 1, 1, TimeUnit.valueOf(DAYS));
将第二个参数从 0 更改为 1 并且成功了!!
我正在 运行 在我的 Mac 上为 HotSpot JDK8 创建一个测试文件。我使用 IntelliJ IDEA 运行 这个 java 程序。
IntelliJ IDEA 2017.1.2
Build #IC-171.4249.39, built on April 25, 2017
JRE: 1.8.0_112-release-736-b16 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.12.5
我在 Runner.java
文件中设置 frequency
时出错。例如,如果我在下面的赋值中设置 25,5 来代替 50,我会得到错误。这是为什么?
int frequency = 50 * runSpecification.objectSize / runSpecification.allocationRatePerSecond; // 25 will fail and yield bug
Exception in thread "main" java.lang.IllegalArgumentException
at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:565)
at eu.plumbr.gc.Runner.run(Runner.java:30)
at eu.plumbr.gc.Runner.main(Runner.java:21)
Process finished with exit code 1
.
└── main
└── java
└── eu
└── plumbr
└── gc
├── Consumer.java
├── Producer.java
├── RunSpecification.java
└── Runner.java
5 directories, 4 files
Consumer.java
package eu.plumbr.gc;
import java.util.Deque;
public class Consumer implements Runnable{
private Deque<byte[]> deque;
public Consumer(Deque<byte[]> deque) {
this.deque = deque;
}
@Override
public void run() {
deque.poll();
}
}
Producer.java
package eu.plumbr.gc;
import java.util.Deque;
public class Producer implements Runnable {
private Deque<byte[]> deque;
private int objectSize;
public Producer(Deque<byte[]> deque, int objectSize) {
this.deque = deque;
this.objectSize = objectSize;
}
@Override
public void run() {
deque.add(new byte[objectSize]);
}
}
Runner.java
package eu.plumbr.gc;
import java.util.ArrayDeque;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Runner {
private RunSpecification runSpecification;
private ScheduledExecutorService executorService;
public Runner(RunSpecification runSpecification, ScheduledExecutorService executorService) {
this.runSpecification = runSpecification;
this.executorService = executorService;
}
public static void main(String[] args) throws InterruptedException {
Runner runner = new Runner(new RunSpecification(10 * 1024, 1024 * 500, 5), Executors.newScheduledThreadPool(2));
runner.run();
}
public void run() {
ArrayDeque<byte[]> deque = new ArrayDeque<byte[]>();
Producer producer = new Producer(deque, runSpecification.objectSize);
Consumer consumer = new Consumer(deque);
int frequency = 50 * runSpecification.objectSize / runSpecification.allocationRatePerSecond; // 25 will fail and yield bug
executorService.scheduleAtFixedRate(producer, 0, frequency, TimeUnit.MILLISECONDS);
executorService.scheduleAtFixedRate(consumer, 1000 * runSpecification.ttl, frequency, TimeUnit.MILLISECONDS);
}
}
RunSpecification.java
package eu.plumbr.gc;
public class RunSpecification {
public int objectSize;
public int allocationRatePerSecond;
public int ttl;
public RunSpecification(int objectSize, int allocationRatePerSecond, int ttl) {
this.objectSize = objectSize;
this.allocationRatePerSecond = allocationRatePerSecond;
this.ttl = ttl;
}
}
参考:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
如果您阅读 javadoc,您将会看到
IllegalArgumentException - 如果周期小于或等于零
不知道你的确切输入,但我会说
int frequency = 50 * runSpecification.objectSize /
runSpecification.allocationRatePerSecond;
frequency
大于 0,但使用 25 则不是
记住你在做整数除法,这可以通过
来验证 int objectSize = 10240;
int allocationRatePerSecond = 512000;
System.out.println(50 * objectSize / allocationRatePerSecond);
System.out.println(25 * objectSize / allocationRatePerSecond);
输出
1
0
根据'Scary Wombat'建议的解决方案,我进行了修改并消除了错误。即,IllegalArgumentException - 如果周期小于或等于零
初始代码:
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(this, 0, 1, TimeUnit.valueOf(DAYS));
更正后的代码:
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(this, 1, 1, TimeUnit.valueOf(DAYS));
将第二个参数从 0 更改为 1 并且成功了!!