gpt4 book ai didi

java - 在notify()之后线程不恢复执行

转载 作者:行者123 更新时间:2023-12-03 13:07:55 24 4
gpt4 key购买 nike

我有两个类(class)(客户和耕作)。客户线程等待,直到一个直到线程通知它。在我的程序中,客户线程在直到直到线程被通知之后才执行它的代码。直到线程继续执行。

Customer.java (客户线程扩展了线程)

import java.util.concurrent.*;
import java.util.*;

public class Customer extends Thread
{
Random random_generator = new Random();

public int minimumQueueLength;
public Set set;
public Iterator iterator;
public boolean placed_in_queue;

public List<Integer> queue_length_list;
public CopyOnWriteArrayList till_set = new CopyOnWriteArrayList();
public Till till, till_to_join;
public final Object lock;

public Customer(CopyOnWriteArrayList till_set)
{
this.till_set = till_set;
this.placed_in_queue = false;
queue_length_list = new ArrayList<Integer>();
lock = new Object();
}

public void run()
{
try
{
place_in_queue();
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}

if(placed_in_queue)
{
synchronized(this.lock)
{

System.out.println(this.getName()+" waiting");

try {
this.lock.wait();

System.out.println(this.getName()+" has been woken");

} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
else
{
}
}

public void place_in_queue() throws InterruptedException
{
placed_in_queue = false;
iterator = till_set.iterator();

while(iterator.hasNext())
{
till = (Till)iterator.next();
queue_length_list.add(till.customer_queue.size());
}

minimumQueueLength =
queue_length_list.indexOf(Collections.min(queue_length_list));

if(minimumQueueLength < 5)
{
try
{
till_to_join = (Till)till_set.get(minimumQueueLength);
till_to_join.customer_queue.put(this);
placed_in_queue = true;
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Till.java (直到线程扩展了Thread)
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.*;

public class Till extends Thread
{
BlockingQueue<String> item_queue = new ArrayBlockingQueue<String>(200);
BlockingQueue<Customer> customer_queue = new ArrayBlockingQueue<Customer>(10);

public Random random;
public Customer c;

public Till(BlockingQueue<String> item_queue) throws InterruptedException
{
this.item_queue = item_queue;
random = new Random();
}

public void run()
{
while(true)
{
try
{
c = customer_queue.take();

synchronized(c.lock)
{
System.out.println(this.getName()+" Waking up : "+c.getName());
c.lock.notify();
System.out.println(c.getName()+" has been notified!");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

CustomerGenerator.java
import java.util.*;
import java.util.concurrent.*;

public class CustomerGenerator extends Thread
{
public int customer_generation_rate;

//0 - slow
//1 - fast

public Random random_generator;

public static BlockingQueue<String> item_queue = new ArrayBlockingQueue<String>(200);
public static CopyOnWriteArrayList till_set = new CopyOnWriteArrayList();

public int i;

public CustomerGenerator(int customer_generation_rate, CopyOnWriteArrayList till_set)
{
this.customer_generation_rate = customer_generation_rate;
this.till_set = till_set;
this.i = 0;
random_generator = new Random();
}

public void run()
{
while(i<1)
{
switch(customer_generation_rate)
{
case 0 : try
{
Thread.sleep(random_generator.nextInt(1000));
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
break;

case 1 : try
{
Thread.sleep(random_generator.nextInt(500));
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
break;

default : customer_generation_rate = 0;
break;
}

Customer customer = new Customer(till_set);
customer.start();
total_customer_count++;
i++;
}
}
}

Driver.java
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Driver
{
public static BlockingQueue<String> item_queue = new ArrayBlockingQueue<>(200);

public static CopyOnWriteArrayList<Till> till_set = new CopyOnWriteArrayList<Till>();

public static Set set;
public static Iterator iterator;

public static int i;

public static final int till_count = 5;

public static Thread till_thread;

public static Till till_object;

public static ExecutorService till_service = Executors.newFixedThreadPool(5);

public static void main(final String[] args) throws InterruptedException
{

for(i=0; i<till_count; i++)
{
till_object = new Till(item_queue);
till_set.add(till_object);
}

final CustomerGenerator customer_generator = new CustomerGenerator(0, till_set);
customer_generator.start();

Thread.sleep(5000);

for(final Till t : till_set)
{
till_service.submit(t);
}
}
}

获得的输出:

线程7等待
线程1唤醒:线程7
线程7已被通知!

预期产量:

线程7等待
线程1唤醒:线程7
线程7已被通知!
线程7已被唤醒

请帮忙。谢谢你。 :)

最佳答案

CustomerGenerator仅在被调用时才生成一位客户。制作它的mcve版本非常清楚:

//i was initialized: i=0;
public void run()
{
while(i<1)
{
final Customer customer = new Customer(till_set);
customer.start();
i++;
}
}

我认为那不是你的意思。
我发现mcve是一种非常有用的技术。它不仅使帮助变得容易得多,而且
是功能强大的调试工具。在很多情况下,当准备一个时,您很可能会发现问题。 mcve应该演示 问题,而不是 而不是您的应用程序。

代码中可能还有其他问题。如需更多帮助,请发布 M cve。
其他一些评论:

CustomerGenerator中,您可以通过以下方式将所有耕作的引用传递给 Customer:
final Customer customer = new Customer(till_set);,以后用于选择耕作。我认为,直到选择计算最好在另一个类中完成,例如TillsManager,它可以让所有的顾客等一堆。

Driver中定义
 public static Till till_object; 
for(i=0; i<5 ; i++)
{
till_object = new Till(item_queue);
till_set.add(till_object);
}

意味着您最终会在 till_set中得到相同对象的5倍。我想你想要的是:
 for(i=0; i<till_count; i++)
{
Till till_object = new Till(item_queue);
till_set.add(till_object);
}

关于java - 在notify()之后线程不恢复执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53272176/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com