Java 通过executor服务启动简单的1生产者2消费者

Java 通过executor服务启动简单的1生产者2消费者,java,multithreading,executorservice,producer-consumer,Java,Multithreading,Executorservice,Producer Consumer,我需要从executor服务器得到一件简单的事情,就是我希望它像simple start()-join()解决方案一样工作(第一段代码) 你想用线程名做点什么,对吗?您在“使用新线程”中创建的线程名称将不会传递到ExecutorService,但这将 class Monitor { private double currItem; private boolean isConsumersShouldWaitProducer = true; private boolean

我需要从executor服务器得到一件简单的事情,就是我希望它像simple start()-join()解决方案一样工作(第一段代码)


你想用线程名做点什么,对吗?您在“使用新线程”中创建的线程名称将不会传递到
ExecutorService
,但这将

class Monitor {

    private double currItem;
    private boolean isConsumersShouldWaitProducer = true;
    private boolean isConsuming = false;
    private String threadNameToWork;

    synchronized void putRandNumber(double producerOutput, String producerName, String threadNameToWork) {
        if (isConsumersShouldWaitProducer) {
            System.out.println("Consumers wait for new Production");
        }
        this.threadNameToWork = threadNameToWork;
        currItem = producerOutput;
        System.out.println("Producer " + producerName + " putRandNumber Item: " + currItem);
        if (currItem > 3) {
            notifyAll();
            isConsumersShouldWaitProducer = false;
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized void consumeRandNumber(String threadName) {
        if (isConsumersShouldWaitProducer) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                System.out.println("Caught Interrupted Exception while waiting to consume currItem: " + e.getMessage());
            }
        }
        if (isConsuming) {
            try {
                this.wait();
                isConsuming = true;
            } catch (InterruptedException e) {
                System.out.println("Caught Interrupted Exception while waiting to consume currItem: " + e.getMessage());
            }
        }
        switch (Thread.currentThread().getName()) {
        /*switch (threadNameToWork) {*/
            case "C-odd":
                isConsuming = true;
                if (currItem % 2 != 0 && threadNameToWork.equals(Thread.currentThread().getName())) {
                    consumeItems(threadName);
                }
                isConsuming = false;
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case "C-even":
                isConsuming = true;
                if (currItem % 2 == 0 && threadNameToWork.equals(Thread.currentThread().getName())) {
                    consumeItems(threadName);
                }
                isConsuming = false;
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }

    private synchronized void consumeItems(String threadName) {
        isConsumersShouldWaitProducer = true;
        String randNumType = "*odd/even*";
        System.out.println("Consumer:" + threadName + " consumed " + randNumType + " Items = " + currItem);
        notifyAll();
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
然后

现在有了名为
thread-1
thread-2

或者在run()方法中设置线程名称


要确保线程已完成,请在返回监视器之前添加此线程

Thread.currentThread().setName(myName)

告诉我们“不能正常工作”是什么意思怎么样?谢谢你的关注。我的意思是executor服务的工作方式与简单的thread start()-join()方法的工作方式不同,嗯,是的。那么,它是如何以同样的方式工作的呢?好的。在一秒钟内,生产者生成随机数,如果数字为奇数,则名为“C-odd”的线程消耗该数字,如果数字为偶数,则名为“C-偶”的线程消耗该数字。当第二次结束时,我返回monitor,其数据成员包含log what thread consumped what number。最后,将此日志发送到单元测试。结束。依赖线程名称是非常糟糕的设计。你可以用
ThreadFactory
进行一次丑陋的黑客攻击,但最好的方法是修复你的设计。不幸的是没有帮助是的,但是我怎么知道哪个线程将成为生产者(线程-1;线程-2或线程-3)以及哪两个将成为消费者?我相信这应该是更好的命名方式。。。在我们创建执行器之后,可能有办法重命名线程。newFixedThreadPool(3)???@BernardCasey编辑了
Thread.currentThread().setName(myName)
,所以我可能需要某种类型的开关盒来在监视器类中重命名。。。是吗?@BernardCasey将name传递给
run()
方法有很多种方法,其中一种方法是,您可以创建`Public void setMyReadName(myName){this.myName=myName;}`方法,该方法将
myName
作为实例变量保存在
Producer
中,然后在
run()
方法中,只需使用`Thread.currentThread().setName(this.myName)`
class Consumer implements Runnable {

    private final SemMonitor monitor;

    Consumer(SemMonitor monitor) {
        this.monitor = monitor;
    }

    @Override
    public void run() {
        long t = System.currentTimeMillis();
        long end = t + 1000;
        while (System.currentTimeMillis() < end) {
            consoleLog(monitor.activeThreadName,false);
            if (/*monitor.semaphore.tryAcquire() && */monitor.activeThreadName.equals( Thread.currentThread().getName())) {

                try {
                    consoleLog(String.valueOf(Thread.currentThread().getName() + " was notified "),monitor.enableLog);
                    monitor.semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                monitor.get(Thread.currentThread().getName());
            }
            try{
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }

    }
}
class Producer implements Runnable {

    private SemMonitor monitor;

    Producer(SemMonitor monitor) {
        this.monitor = monitor;
    }

    @Override
    public void run() {
        String threadNameToWork;
        Integer randNum;
        long t = System.currentTimeMillis();
        long end = t + 500;
        while (System.currentTimeMillis() < end) {
            if (monitor.semaphore.tryAcquire()) {
                randNum = ((Number) (random() * 100)).intValue();
                if (randNum % 2 == 0) {
                    threadNameToWork = "C-even";
                } else {
                    threadNameToWork = "C-odd";
                }
                try {
                    monitor.putItem(randNum, Thread.currentThread().getName(), threadNameToWork);
                    Thread.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
class Monitor {

    private double currItem;
    private boolean isConsumersShouldWaitProducer = true;
    private boolean isConsuming = false;
    private String threadNameToWork;

    synchronized void putRandNumber(double producerOutput, String producerName, String threadNameToWork) {
        if (isConsumersShouldWaitProducer) {
            System.out.println("Consumers wait for new Production");
        }
        this.threadNameToWork = threadNameToWork;
        currItem = producerOutput;
        System.out.println("Producer " + producerName + " putRandNumber Item: " + currItem);
        if (currItem > 3) {
            notifyAll();
            isConsumersShouldWaitProducer = false;
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized void consumeRandNumber(String threadName) {
        if (isConsumersShouldWaitProducer) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                System.out.println("Caught Interrupted Exception while waiting to consume currItem: " + e.getMessage());
            }
        }
        if (isConsuming) {
            try {
                this.wait();
                isConsuming = true;
            } catch (InterruptedException e) {
                System.out.println("Caught Interrupted Exception while waiting to consume currItem: " + e.getMessage());
            }
        }
        switch (Thread.currentThread().getName()) {
        /*switch (threadNameToWork) {*/
            case "C-odd":
                isConsuming = true;
                if (currItem % 2 != 0 && threadNameToWork.equals(Thread.currentThread().getName())) {
                    consumeItems(threadName);
                }
                isConsuming = false;
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case "C-even":
                isConsuming = true;
                if (currItem % 2 == 0 && threadNameToWork.equals(Thread.currentThread().getName())) {
                    consumeItems(threadName);
                }
                isConsuming = false;
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }

    private synchronized void consumeItems(String threadName) {
        isConsumersShouldWaitProducer = true;
        String randNumType = "*odd/even*";
        System.out.println("Consumer:" + threadName + " consumed " + randNumType + " Items = " + currItem);
        notifyAll();
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                                       .setNameFormat("thread-%d").build()
ExecutorService exec = Executors.newSingleThreadExecutor(namedThreadFactory);
Thread.currentThread().setName(myName)
service.shutdown();
while (!service.awaitTermination(10, TimeUnit.SECONDS)) {
   log.info("Awaiting completion of threads.");
}