我想让"runnable"以5tps的速度运行。这不是并行执行。
package tt;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class mySpawner {
public int tillDone = 0;
public int tillMax = 0;
public ArrayList arrayList;
private myWorker myworking;
private ScheduledExecutorService service = Executors.newScheduledThreadPool(50);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println(System.nanoTime());
Thread.sleep(7000);
} catch (InterruptedException ex) {
Logger.getLogger(mySpawner.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
public void activate() {
try {
service = Executors.newScheduledThreadPool(50);
service.scheduleAtFixedRate(runnable, 0, 200, TimeUnit.MILLISECONDS);
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
public void deactivate() {
service.shutdown();
}
}
考虑一下:
- 你的任务在执行过程中休眠7秒
- 每200ms调度一个新任务
- 你的执行器中只有50个线程
很明显,我希望,您将在几秒钟内耗尽池中的线程,并且您将失去并行性。你需要更好地平衡这一点,要么降低速度,要么减少睡眠时间。增加池大小没有帮助,您仍然会耗尽线程。
scheduleAtFixedRate
只生成一个线程,但是执行一个固定速率的可运行线程。
- 动作在比给定周期更短的时间内运行:在这种情况下,它恰好在指定的周期内重生。
- 操作运行时间较长(您的情况):操作立即重新开始。
如果你想有理想的行为,你可以使用以下模式:只执行一次runnable:
service.schedule(runnable, 0, TimeUnit.MILLISECONDS);
但是在可运行的run
方法中添加下一个调用
service.schedule(runnable, 200, TimeUnit.MILLISECONDS);
尽管如此,考虑skaffman在答案中描述的算术
更新: Howard是对的,我的第一个例子是错误的。
如果你改变你的active()
方法,我验证了这是有效的:
service = Executors.newScheduledThreadPool(50);
new Thread() {
public void run() {
long nextTime = System.currentTimeMillis();
while (true) {
service.submit(runnable);
long waitTime = nextTime - System.currentTimeMillis();
Thread.sleep(Math.max(0, waitTime));
nextTime += 200;
}
}
}.start();