Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何知道线程是被唤醒还是被时间分割(生产者-消费者)_Java_Multithreading - Fatal编程技术网

Java 如何知道线程是被唤醒还是被时间分割(生产者-消费者)

Java 如何知道线程是被唤醒还是被时间分割(生产者-消费者),java,multithreading,Java,Multithreading,我正在学习java中的多线程,我遇到了一个我无法理解的行为 在此之前,有一些解释:制作人需要制作,直到列表满为止。生产时,没有任何东西能阻止消费者消费。消费者消费,直到列表为空。只有当列表中有您没有调用interrupt()方法来中断线程时,生产者才开始生产。在main方法中尝试以下代码: producer.start(); consumer.start(); producer.interrupt(); consumer.interrupt(); 以下是一个示例输出: 2015年10月1日星期

我正在学习java中的多线程,我遇到了一个我无法理解的行为


在此之前,有一些解释:制作人需要制作,直到列表满为止。生产时,没有任何东西能阻止消费者消费。消费者消费,直到列表为空。只有当列表中有您没有调用
interrupt()
方法来中断线程时,生产者才开始生产。在
main
方法中尝试以下代码:

producer.start();
consumer.start();
producer.interrupt();
consumer.interrupt();
以下是一个示例输出:

2015年10月1日星期四10:56:10国际标准时间10点
列表没有开始生产的最小数量
我被打断了
获得2015年10月1日星期四10:56:10 IST 10点
获得2015年10月1日星期四10:56:10国际标准时间9点
获得2015年10月1日星期四10:56:10 IST 8点
获得2015年10月1日星期四10:56:10 IST 7点
获得2015年10月1日星期四10:56:10 IST 6点
2015年10月1日星期四10:56:10国际标准时间5点
2015年10月1日星期四10:56:10国际标准时间4点
2015年10月1日星期四10:56:10国际标准时间3点
2015年10月1日星期四10:56:10国际标准时间2点
2015年10月1日星期四10:56:10国际标准时间1点
已于2015年10月1日星期四10:56:10获取0
我被打断了
将2015年10月1日星期四10:56:10 IST设置为0

注意事项(摘自官方文件):

  • 线程通过调用要中断的线程的
    thread
    对象上的
    interrupt
    来发送中断。为了使中断机制正常工作,被中断的线程必须支持自己的中断
  • 中断机制使用称为
    中断状态的内部标志实现。调用
    Thread.interrupt
    设置此标志。当线程通过调用静态方法
    thread.interrupted
    检查中断时,中断状态被清除。一个线程用来查询另一个线程的中断状态的非静态
    isInterrupted
    方法不会更改中断状态标志

  • main
    中的变量名称不匹配,请更正它没有被调用,因为您没有中断代码中的任何线程。您需要调用
    Thread.interrupt()
    来中断线程。请检查productor、consumidor的变量名。是否应该是“生产者”和“消费者”?@ErwinBolwidt然后
    notifyAll()
    在这种情况下没有帮助?您的线程是否被唤醒或时间切片是无关紧要的,并且无法从代码中检测。你的问题毫无意义。我怎么知道某个线程是否被“唤醒”,而不是从时间上恢复-slice@JohnnyWiller你不能。如果你可以的话,会有什么不同?@JohnnyWiller“睡眠”和“醒来”的发生是因为你的程序所做的事情。线程只能通过调用使其睡眠的方法来“睡眠”(例如,
    thread.sleep()
    object.wait()
    )。当方法调用返回时,这意味着您的线程被“唤醒”。另一方面,时间切片对于程序来说是完全不可见的。它不是语言的一部分,也不是任何库调用都能做到的。它只是发生了,你的程序甚至无法知道它发生的时间和地点。
    class Consumer extends Thread {
    
        private MyList list;
        public Consumer(MyList list) {
           this.list = list;    
        }
        public void run() {
        for (int i = 0; i < 1000; i++) {
            try {
               list.get();
            } catch (InterruptedException e) {
               System.out.println("I WAS INTERRUPTED 2");
            }
        }
        }
    }
    
        public class MyList {
    
            private String[] dates = new String[100];
            private int index = -1;
    
            public int getIndex() {
               return index;
            }
    
            public synchronized void put() throws InterruptedException {
    
            if ((getIndex() + 1) == 100) {     
                System.out.println("List is full");
                wait();
            }
    
    
        /**
         * Here I need to know if this thread was woke up by the consumer, or it was 'restaured' due time-slice
         * 
         */
    
            if (Thread.currentThread().isInterrupted() && getIndex() >= 10) {
                System.out.println("List doesn't have the minimun quantity to start a production");
                wait();
            }
    
            dates[++index] = new Date().toString();
            System.out.println("put " + dates[index] + " at " + index);
            notifyAll();
            }
    
            public synchronized void get() throws InterruptedException {
    
            if (getIndex() < 0)
                wait();
    
            System.out.println("got " + dates[index--] + " at " + (index + 1));
    
          /**
         * Basically, to this example work I would need to put, if (getIndex() < 10) notifyAll() here,
         *  but that is a behavior for the producer and should not be in the consumer
         * 
         */
             notifyAll();
    
            }
        }
    
    public class Main {
    
        public static void main(String[] args) {
    
        MyList list = new MyList();
    
        Thread producer = new Producer(list);
        Thread consumer = new Consumer(list);
    
        producer.start();
        consumer.start();
        }
    }
    
    ....
    ....
    put Thu Oct 01 02:15:12 BRT 2015 at 93
    put Thu Oct 01 02:15:12 BRT 2015 at 94
    put Thu Oct 01 02:15:12 BRT 2015 at 95
    put Thu Oct 01 02:15:12 BRT 2015 at 96
    put Thu Oct 01 02:15:12 BRT 2015 at 97
    put Thu Oct 01 02:15:12 BRT 2015 at 98
    put Thu Oct 01 02:15:12 BRT 2015 at 99
    List is full
    got Thu Oct 01 02:15:12 BRT 2015 at 99
    put Thu Oct 01 02:15:12 BRT 2015 at 99 <- this wouldn't happen
    List is full
    got Thu Oct 01 02:15:12 BRT 2015 at 99
    put Thu Oct 01 02:15:12 BRT 2015 at 99 <- this wouldn't happen
    List is full
    ...
    ...
    
    producer.start();
    consumer.start();
    producer.interrupt();
    consumer.interrupt();