如果我理解你的问题,一种方法是自适应地休眠线程,类似于在Java中完成视频播放。如果您知道自己想要 50% 的核心利用率,则您的算法应休眠约 0.5 秒 - 可能分布在一秒内(例如,0.25 秒计算,0.25 秒睡眠,例如 t.c.)。这是我的视频播放器的一个例子。
long starttime = 0;
if (frameCount == 0) {
starttime = System.currentTimeMillis();
}
starttime += (1000.0 / fps);
LockSupport.parkNanos((long)(Math.max(0,
starttime - System.currentTimeMillis()) * 1000000));
此代码将根据帧/秒值休眠。
若要限制内存使用量,可以将对象创建包装到工厂方法中,并使用某种具有有限允许值的信号量作为字节来限制估计的总对象大小(您需要估计各种对象的大小以配给信号量)。
package concur;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class MemoryLimited {
private static Semaphore semaphore = new Semaphore(1024 * 1024, true);
public static byte[] createArray(int size) throws InterruptedException {
semaphore.acquire(size);
return new byte[size];
}
public static void releaseArray(byte[] array) {
semaphore.release(array.length);
}
static final int N = 600000;
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(2);
Runnable run = new Runnable() {
@Override
public void run() {
Random rnd = new Random();
for (int i = 0; i < 10; i++) {
try {
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
byte[] array = createArray(N);
System.out.printf("%s %d: %s (%d)%n",
Thread.currentThread().getName(),
System.currentTimeMillis(), array,
semaphore.availablePermits());
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
releaseArray(array);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
exec.submit(run);
exec.submit(run);
exec.shutdown();
}
}