Java Thread.sleep不';t强制上下文切换

Java Thread.sleep不';t强制上下文切换,java,multithreading,concurrency,thread-sleep,java-threads,Java,Multithreading,Concurrency,Thread Sleep,Java Threads,主线程创建子线程。家长需要孩子做一些工作,但不是全部,所以家长必须等到孩子完成那个工作(孩子会继续做其他的工作) 我希望通过监视器实现这一点,因此我编写了以下代码: public class WaitChildThreadMonitor { public static final int TOTAL_COUNT_AMOUNT = 1_000; static int count = 0; class Child implements Runnable { @Override

主线程创建子线程。家长需要孩子做一些工作,但不是全部,所以家长必须等到孩子完成那个工作(孩子会继续做其他的工作)

我希望通过监视器实现这一点,因此我编写了以下代码:

public class WaitChildThreadMonitor {

public static final int TOTAL_COUNT_AMOUNT = 1_000;
static int count = 0;

class Child implements Runnable {

    @Override
    public void run() {
        work();
    }

    public synchronized void work() {

        letParentWaitForThis();

        for (int i = 0; i < TOTAL_COUNT_AMOUNT; i++)
            ++WaitChildThreadMonitor.count;

        this.notifyAll();

        // More child work that parent doesn't need right now
        //  ...
        for (int i = 0; i < TOTAL_COUNT_AMOUNT; i++)
            ++WaitChildThreadMonitor.count;
    }

    private void letParentWaitForThis() {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {}

    }

    public synchronized void waitForWork() throws InterruptedException {
        this.wait();
    }
}

void main() throws InterruptedException {

    Child child = new Child();
    Thread childThread = new Thread(child);

    // If the next two methods doesn't execute atomically,
    //      parent execution gets blocked forever
    childThread.start();
    child.waitForWork();

    System.out.printf("Count value is %d\n", WaitChildThreadMonitor.count);
    childThread.join();

}

public static void main(String[] args) throws InterruptedException {
    (new WaitChildThreadMonitor()).main();
}
公共类WaitChildThreadMonitor{
公共静态最终整数总计数金额=1000;
静态整数计数=0;
类子级实现可运行{
@凌驾
公开募捐{
工作();
}
公共同步无效工作(){
让父母为之等待();
对于(int i=0;i
}

问题是,如果孩子在完成主要工作后,在家长执行“child.waitForWork()”中的“this.wait()”之前执行“this.notifyAll()”,家长将不会收到通知,并将永远被阻止

我试图在孩子开始工作之前使用Thread.sleep()方法强制进行上下文切换来解决这个问题。它似乎不像预期的那样工作

有睡眠和无睡眠时,有时家长会被阻止,程序永远不会结束,有时会正常结束(我猜是因为家长在通知孩子之前等待)

我怎样才能解决这个问题


提前谢谢

如果您要等待的事情已经发生,则不能调用
等待。这就是调用
wait
的方法是
synchronized
——因此您可以检查表示您正在等待的内容的共享状态。

因此这是一个标准的生产者-消费者问题。很久以前,我只使用
synchronized
wait notify
编写了一个实现。我看不出你的代码产生了什么;这段代码只使用int作为生成的对象。更改
存储
中的数组类型以获得其他类类型

package quicktest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Brenden Towey
 */
public class ProducerConsumer {
   public static void main(String[] args) throws InterruptedException {
      Storage circularBuffer = new Storage();
      Counter producer1 = new Counter( circularBuffer, 1000 );
      Counter producer2 = new Counter( circularBuffer, 2000 );
      Counter producer3 = new Counter( circularBuffer, 3000 );
      Counter producer4 = new Counter( circularBuffer, 4000 );

      ExecutorService exe = Executors.newCachedThreadPool();

      exe.execute( producer1 );
      exe.execute( producer2 );
      exe.execute( producer3 );
      exe.execute( producer4 );

      Printer consumer = new Printer( circularBuffer );
      exe.execute( consumer );

      Thread.sleep( 100 );// wait a bit
      exe.shutdownNow();
      exe.awaitTermination( 10, TimeUnit.SECONDS );
   }
}

// Producer
class Counter implements Runnable {
   private final Storage output;
   private final int startingValue;

   public Counter(Storage output, int startingValue) {
      this.output = output;
      this.startingValue = startingValue;
   }

   @Override
   public void run() {
         try {
            for( int i = startingValue; ; i++ ) 
               output.put(i);
         } catch (InterruptedException ex) {
            // exit...
         }
   }

}

class Storage {
   private final int[] buffer = new int[20];
   private int head;
   private int count;
   public synchronized void put( int i ) throws InterruptedException {
      while( count == buffer.length ) wait();// full
      buffer[head++] = i;
      head %= buffer.length;
      count++;
      notifyAll();
   }
   public synchronized int get() throws InterruptedException {
      while( count == 0 ) wait(); // empty
      int tail = (head - count) % buffer.length;
      tail = (tail < 0) ? tail + buffer.length : tail;
      int retval = buffer[tail];
      count--;
      notifyAll();
      return retval;
   }
}

// Consumer
class Printer implements Runnable {
   private final Storage input;

   public Printer(Storage input) {
      this.input = input;
   }

   @Override
   public void run() {
         try {
            for( ;; ) 
               System.out.println( input.get() );
         } catch (InterruptedException ex) {
            // exit...
         }
   }
}
packagequicktest;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
/**
*
*@作者布伦登·托维
*/
公共类生产者消费者{
公共静态void main(字符串[]args)引发InterruptedException{
存储循环缓冲=新存储();
计数器生产商1=新计数器(循环缓冲,1000);
计数器生产商2=新计数器(circularBuffer,2000年);
计数器生产商3=新计数器(循环缓冲器,3000);
计数器生产商4=新计数器(循环缓冲,4000);
ExecutorService exe=Executors.newCachedThreadPool();
exe.execute(producer1);
exe.execute(producer2);
exe.execute(producer3);
exe.execute(producer4);
打印机消费者=新打印机(循环缓冲);
exe.execute(消费者);
Thread.sleep(100);//稍等
exe.shutdownNow();
等待终止(10,TimeUnit.SECONDS);
}
}
//制作人
类计数器实现可运行{
专用最终存储输出;
私人最终整数起始值;
公共计数器(存储输出,int启动值){
这个。输出=输出;
this.startingValue=startingValue;
}
@凌驾
公开募捐{
试一试{
for(int i=起始值;;i++)
产出.产出(i);
}捕获(中断异常例外){
//退出。。。
}
}
}
类存储{
私有最终整数[]缓冲区=新整数[20];
私人内部主管;
私人整数计数;
公共同步的void put(inti)抛出InterruptedException{
while(count==buffer.length)wait();//已满
缓冲区[head++]=i;
头%=缓冲区长度;
计数++;
notifyAll();
}
public synchronized int get()引发InterruptedException{
while(count==0)wait();//为空
int tail=(人头计数)%buffer.length;
尾部=(尾部<0)?尾部+缓冲区。长度:尾部;
int retval=缓冲区[尾];
计数--;
notifyAll();
返回返回;
}
}
//消费者
类打印机实现可运行{
专用最终存储输入;
公用打印机(存储输入){
这个输入=输入;
}
@凌驾
公开募捐{
试一试{
对于(;;)
System.out.println(input.get());
}捕获(中断异常例外){
//退出。。。
}
}
}

这是生产者和消费者的基本问题。子对象产生结果,父对象消耗这些结果。使用标准方法解决这个问题,它会起作用…强制上下文切换。。。在Java语言中没有“上下文切换”这样的事情,因此在Java中也没有强制执行的方法。假设在一个有四个CPU的系统上有三个可运行线程。其中一个线程调用
sleep()
。这将如何影响其他线程?不会的。其他所有已经可以运行的线程都将运行。添加了一个布尔值,它现在可以正常工作了!谢谢!!