上下文在Java中的多个线程之间切换

时间:2016-02-09 13:21:28

标签: java multithreading context-switching

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

我的问题是关于性能含义,其中有人认为“CPU浪费更多时间进行上下文切换,而花费更少时间进行实际工作”。但是看一下这个例子,我认为上下文切换只有在CPU完成所需的操作集时才会发生。那么引用声明背后的逻辑是什么?请查看附带的示例(Courtesy: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."); 
    }
}

1 个答案:

答案 0 :(得分:0)

  

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

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

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