java吧 关注:1,225,065贴子:12,681,206
  • 11回复贴,共1

请问这种一边取 一边加的队列,怎么写多线程?

只看楼主收藏回复

如图一,这个方法能按我期望,输出15。图二输出就是0了。
好像在第一个元素出队之后,while循环就退出了



IP属地:上海来自Android客户端1楼2024-05-30 22:06回复
    自学java,有很多不靠谱没学过的东西,希望大佬指点一下


    IP属地:上海来自Android客户端2楼2024-05-30 22:06
    回复
      d


      IP属地:上海来自Android客户端3楼2024-05-30 23:21
      回复
        你创建的线程把队列里的5给poll出来后,还没执行到放入4这一步,主线程的while循环此时检查队列为空,就退出去了。


        IP属地:江苏来自Android客户端5楼2024-05-31 01:15
        回复
          因为你没有等线程执行完


          IP属地:四川6楼2024-05-31 01:21
          回复
            一边取一边加的队列的多线程程序一般是用生产者消费者模式来写。
            import java.util.concurrent.ConcurrentLinkedQueue;
            public class ProducerConsumerPattern {
            public static void producerConsumerSum(int n) {
            ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
            Thread producer = new Thread(() -> {
            for (int i = n; i >= 1; i--) {
            queue.add(i);
            }
            });
            Thread consumer = new Thread(() -> {
            int sum = 0;
            while (!queue.isEmpty()) {
            Integer num = queue.poll();
            if (num != null) {
            sum += num;
            }
            }
            System.out.println("Sum: " + sum);
            });
            producer.start();
            consumer.start();
            try {
            producer.join();
            consumer.join();
            } catch (InterruptedException e) {
            e.printStackTrace();
            }
            }
            public static void main(String[] args) {
            int n = 5;
            producerConsumerSum(n);
            }
            }


            IP属地:江苏来自Android客户端7楼2024-05-31 01:29
            收起回复
              看 Atomic 相关类


              IP属地:重庆来自Android客户端8楼2024-05-31 07:27
              回复
                之前的写法有bug,消费者还是会提前退出,导致输出可能为Sum: 0。这是修改过的。另外,这个目前只适用于单生产者单消费者的情况,如果要适配多生产者多消费者的模式需要进行相应的修改。
                import java.util.concurrent.ConcurrentLinkedQueue;
                public class Main {
                private static final Integer END_MARKER = Integer.MIN_VALUE;
                public static void producerConsumerSum(int n) {
                ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
                Thread producer = new Thread(() -> {
                for (int i = n; i >= 1; i--) {
                queue.add(i);
                }
                queue.add(END_MARKER); // 放入结束标记
                });
                Thread consumer = new Thread(() -> {
                int sum = 0;
                while (true) {
                Integer num = queue.poll();
                if (num != null) {
                if (num.equals(END_MARKER)) {
                break;
                }
                sum += num;
                }
                }
                System.out.println("Sum: " + sum);
                });
                producer.start();
                consumer.start();
                try {
                producer.join();
                consumer.join();
                } catch (InterruptedException e) {
                e.printStackTrace();
                }
                }
                public static void main(String[] args) {
                int n = 5;
                producerConsumerSum(n);
                }
                }


                IP属地:江苏9楼2024-05-31 09:20
                回复
                  生产者消费者模式,用阻塞队列啊


                  IP属地:陕西来自Android客户端10楼2024-05-31 14:45
                  回复
                    转行吧


                    IP属地:北京来自Android客户端12楼2024-06-01 16:45
                    收起回复