java 忙等待,Java Concurrency JDK 1.6:忙碌等待比信令好吗?有效的Java#51

Joshua Bloch的“Effective

Java”,第51项不是依赖于线程调度程序,也不是在可运行状态下不必要地保留线程.引用文字:

The main technique for keeping the number of runnable threads down is to have each thread

do a small amount of work and then wait for some condition using Object.wait or for some

time to elapse using Thread.sleep. Threads should not busy-wait,repeatedly checking a data

structure waiting for something to happen. Besides making the program vulnerable to the

vagaries of the scheduler,busy-waiting can greatly increase the load on the processor,

reducing the amount of useful work that other processes can accomplish on the same machine.

然后继续显示忙碌等待的微基准测试与正确使用信号.在书中,忙碌等待执行17次往返/秒,而等待/通知版本每秒执行23,000次往返.

但是,当我在JDK 1.6上尝试相同的基准测试时,我看到恰恰相反 – 忙等待是760K往返/秒,而等待/通知版本是53.3K往返/秒 – 也就是说,等待/通知应该是~1400时间更快,但结果慢了约13倍?

我知道繁忙的等待并不好,信号仍然更好 – 忙等待版本的cpu利用率约为50%,而等待/通知版本的停留率约为30% – 但有没有解释数字的东西?

如果它有帮助,我在Win 7 x64(核心i5)上运行JDK1.6(32位).

更新:来源如下.要运行繁忙的工作台,请将PingPongQueue的基类更改为BusyWorkQueue

import java.util.LinkedList;

import java.util.List;

abstract class SignalWorkQueue {

private final List queue = new LinkedList();

private boolean stopped = false;

protected SignalWorkQueue() { new WorkerThread().start(); }

public final void enqueue(Object workItem) {

synchronized (queue) {

queue.add(workItem);

queue.notify();

}

}

public final void stop() {

synchronized (queue) {

stopped = true;

queue.notify();

}

}

protected abstract void processItem(Object workItem)

throws InterruptedException;

private class WorkerThread extends Thread {

public void run() {

while (true) { // Main loop

Object workItem = null;

synchronized (queue) {

try {

while (queue.isEmpty() && !stopped)

queue.wait();

} catch (InterruptedException e) {

return;

}

if (stopped)

return;

workItem = queue.remove(0);

}

try {

processItem(workItem); // No lock held

} catch (InterruptedException e) {

return;

}

}

}

}

}

// HORRIBLE PROGRAM - uses busy-wait instead of Object.wait!

abstract class BusyWorkQueue {

private final List queue = new LinkedList();

private boolean stopped = false;

protected BusyWorkQueue() {

new WorkerThread().start();

}

public final void enqueue(Object workItem) {

synchronized (queue) {

queue.add(workItem);

}

}

public final void stop() {

synchronized (queue) {

stopped = true;

}

}

protected abstract void processItem(Object workItem)

throws InterruptedException;

private class WorkerThread extends Thread {

public void run() {

final Object QUEUE_IS_EMPTY = new Object();

while (true) { // Main loop

Object workItem = QUEUE_IS_EMPTY;

synchronized (queue) {

if (stopped)

return;

if (!queue.isEmpty())

workItem = queue.remove(0);

}

if (workItem != QUEUE_IS_EMPTY) {

try {

processItem(workItem);

} catch (InterruptedException e) {

return;

}

}

}

}

}

}

class PingPongQueue extends SignalWorkQueue {

volatile int count = 0;

protected void processItem(final Object sender) {

count++;

SignalWorkQueue recipient = (SignalWorkQueue) sender;

recipient.enqueue(this);

}

}

public class WaitQueuePerf {

public static void main(String[] args) {

PingPongQueue q1 = new PingPongQueue();

PingPongQueue q2 = new PingPongQueue();

q1.enqueue(q2); // Kick-start the system

// Give the system 10 seconds to warm up

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

// Measure the number of round trips in 10 seconds

int count = q1.count;

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

}

System.out.println(q1.count - count);

q1.stop();

q2.stop();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值