0

什么构成上下文切换?我知道有时可以使用 sleep() 。我遇到了一个使用 wait() 和 notify() 组合来执行线程间通信的示例,以便一个线程(生产者类)提供数据集,然后等待另一个线程(消费者类)消耗它。

我的问题是关于性能影响,有人认为“CPU 浪费了更多时间进行上下文切换,而浪费了更少的时间进行实际工作”。但是看看这个例子,我认为只有在 CPU 完成所需的一组操作时才会发生上下文切换。那么上面引用的语句背后的逻辑是什么?请找到随附的示例(礼貌:Osborne The Complete Reference Java)。

/*An implementation of a producer and consumer.*/

class Q {
int n;
boolean valueSet = false;

synchronized int get() {
    if(!valueSet)
    try {
      wait();
    } catch(InterruptedException e) {
      System.out.println("InterruptedException caught");
    }
    System.out.println("Got: " + n);
    valueSet = false;
    notify();
    return n;
}

synchronized void put(int n) {
    if(valueSet)
    try {
        wait();
    } catch(InterruptedException e) {
        System.out.println("InterruptedException caught");
    }
    this.n = n;
    valueSet = true;
    System.out.println("Put: " + n);
    notify();
}
}


class Producer implements Runnable {
    Q q;
    Producer(Q q) {
        this.q = q;
        new Thread(this, "Producer").start();
    }
    public void run() {
        int i = 0;
        while(true) {
            q.put(i++);
        }
    }
}

class Consumer implements Runnable {
    Q q;
    Consumer(Q q) {
        this.q = q;
        new Thread(this, "Consumer").start();
    }
    public void run() {
        while(true) {
            q.get();
        }
    }
}


class PCFixed {
    public static void main(String args[]) {
        Q q = new Q();
        new Producer(q);
        new Consumer(q); 
        System.out.println("Press Control-C to stop."); 
    }
}
4

1 回答 1

0

CPU 在上下文切换上浪费了更多时间,而在实际工作上浪费了更少的时间。

这是因为,在上下文切换期间,操作系统内核必须为当前线程保存 cpu 寄存器的状态,然后为下一个要执行的线程加载这些寄存器的正确状态。这是内核在与应用程序代码无关的上下文切换期间必须做的额外工作。

这样做的另一个副作用是,由于上下文切换,我们失去了引用的局部性。

于 2016-02-09T13:33:53.857 回答