Java中队列中线程的执行
我有以下练习: 开发多线程应用程序。 使用java.util.concurrent opportunities 不要使用:已同步、阻塞队列、阻塞队列 希望访问资源的所有实体都必须是线程。使用 面向对象的机会 我的任务是: 免费收银台。快餐店有几个收银台。客户在特定的收银台排队,但可能会离开 如果那里的排队人数减少或消失,请转到另一个收银台 这是我的解决方案 所以,正如您所看到的,服务队列受到了干扰 当客户3被送达时,客户6必须开始送达,但客户50必须这样做。当客户5被送达时,客户4必须开始送达,但客户7必须这样做。当客户7被送达时,我不知道为什么,但客户6移动到收银台1开始服务,尽管客户4必须开始服务Java中队列中线程的执行,java,multithreading,concurrency,reentrantlock,Java,Multithreading,Concurrency,Reentrantlock,我有以下练习: 开发多线程应用程序。 使用java.util.concurrent opportunities 不要使用:已同步、阻塞队列、阻塞队列 希望访问资源的所有实体都必须是线程。使用 面向对象的机会 我的任务是: 免费收银台。快餐店有几个收银台。客户在特定的收银台排队,但可能会离开 如果那里的排队人数减少或消失,请转到另一个收银台 这是我的解决方案 所以,正如您所看到的,服务队列受到了干扰 当客户3被送达时,客户6必须开始送达,但客户50必须这样做。当客户5被送达时,客户4必须开始送达,
我是多线程的新手,所以我需要一个建议,如何让我的应用程序正常工作您在标题中提到了队列,但在代码中没有使用它们。事实上,当第一个客户机(客户机5)到达收银台1时,收银台被锁定以服务于该客户机
//client code
while (true) {
if (cashDesk.getLock().tryLock()) { //the cashdesk is locked
try {
cashDesk.serveClient(this);
同时,由于有服务时间,其他客户也来了。所以客户端4和客户端7正在收银台1等待当client5被服务时,client5释放锁
//client code
cashDesk.getLock().unlock();
因此,下一个被服务的是第一个获取锁的,因为它是一个无限循环,所以您无法知道每个客户机在代码中的哪个位置。所以client7在client4之前先抓住它。此外,在阅读您的输出时,client2也会事先获取它。我建议您移除锁并使用变量指定顺序
//CashDesk
Client current=null;
public void nextClient()
{
if(clients.size()==0)
current=null;
else
current = clients.get(0);
}
替换代码后面的部分
while (true) {
if (cashDesk.getLock().tryLock()) {
try {
cashDesk.serveClient(this);
} catch (ResourceException e) {
LOG.error("ResourceException!!! ", e);
} finally {
cashDesk.getLock().unlock();
break;
}
} else {
if (canChooseAnotherCashDesk()) {
cashDesk.removeClient(this);
}
}
}
借
您在标题中提到了队列,但在代码中没有使用它们。事实上,当第一个客户机(客户机5)到达收银台1时,收银台被锁定以服务于该客户机
//client code
while (true) {
if (cashDesk.getLock().tryLock()) { //the cashdesk is locked
try {
cashDesk.serveClient(this);
同时,由于有服务时间,其他客户也来了。所以客户端4和客户端7正在收银台1等待当client5被服务时,client5释放锁
//client code
cashDesk.getLock().unlock();
因此,下一个被服务的是第一个获取锁的,因为它是一个无限循环,所以您无法知道每个客户机在代码中的哪个位置。所以client7在client4之前先抓住它。此外,在阅读您的输出时,client2也会事先获取它。我建议您移除锁并使用变量指定顺序
//CashDesk
Client current=null;
public void nextClient()
{
if(clients.size()==0)
current=null;
else
current = clients.get(0);
}
替换代码后面的部分
while (true) {
if (cashDesk.getLock().tryLock()) {
try {
cashDesk.serveClient(this);
} catch (ResourceException e) {
LOG.error("ResourceException!!! ", e);
} finally {
cashDesk.getLock().unlock();
break;
}
} else {
if (canChooseAnotherCashDesk()) {
cashDesk.removeClient(this);
}
}
}
借
您在标题中提到了队列,但在代码中没有使用它们。事实上,当第一个客户机(客户机5)到达收银台1时,收银台被锁定以服务于该客户机
//client code
while (true) {
if (cashDesk.getLock().tryLock()) { //the cashdesk is locked
try {
cashDesk.serveClient(this);
同时,由于有服务时间,其他客户也来了。所以客户端4和客户端7正在收银台1等待当client5被服务时,client5释放锁
//client code
cashDesk.getLock().unlock();
因此,下一个被服务的是第一个获取锁的,因为它是一个无限循环,所以您无法知道每个客户机在代码中的哪个位置。所以client7在client4之前先抓住它。此外,在阅读您的输出时,client2也会事先获取它。我建议您移除锁并使用变量指定顺序
//CashDesk
Client current=null;
public void nextClient()
{
if(clients.size()==0)
current=null;
else
current = clients.get(0);
}
替换代码后面的部分
while (true) {
if (cashDesk.getLock().tryLock()) {
try {
cashDesk.serveClient(this);
} catch (ResourceException e) {
LOG.error("ResourceException!!! ", e);
} finally {
cashDesk.getLock().unlock();
break;
}
} else {
if (canChooseAnotherCashDesk()) {
cashDesk.removeClient(this);
}
}
}
借
您在标题中提到了队列,但在代码中没有使用它们。事实上,当第一个客户机(客户机5)到达收银台1时,收银台被锁定以服务于该客户机
//client code
while (true) {
if (cashDesk.getLock().tryLock()) { //the cashdesk is locked
try {
cashDesk.serveClient(this);
同时,由于有服务时间,其他客户也来了。所以客户端4和客户端7正在收银台1等待当client5被服务时,client5释放锁
//client code
cashDesk.getLock().unlock();
因此,下一个被服务的是第一个获取锁的,因为它是一个无限循环,所以您无法知道每个客户机在代码中的哪个位置。所以client7在client4之前先抓住它。此外,在阅读您的输出时,client2也会事先获取它。我建议您移除锁并使用变量指定顺序
//CashDesk
Client current=null;
public void nextClient()
{
if(clients.size()==0)
current=null;
else
current = clients.get(0);
}
替换代码后面的部分
while (true) {
if (cashDesk.getLock().tryLock()) {
try {
cashDesk.serveClient(this);
} catch (ResourceException e) {
LOG.error("ResourceException!!! ", e);
} finally {
cashDesk.getLock().unlock();
break;
}
} else {
if (canChooseAnotherCashDesk()) {
cashDesk.removeClient(this);
}
}
}
借
所以,正如您所看到的,服务队列受到了干扰
它没有被打扰。它实际上是按照你的设计工作的
ReentrantLock文档:
此类的构造函数接受可选的公平性参数。
如果设置为true,则在争用下,锁会优先授予对
等待时间最长的线程否则此锁不保证任何
特定的访问顺序。使用公平锁的程序被许多人访问
线程可能显示较低的总体吞吐量(即较慢;通常
比使用默认设置的要慢得多),但具有更小的
获得锁和保证不饥饿的时间差异
但是请注意,锁的公平性并不保证
线程调度。因此,使用公平锁的多个线程中的一个可能会
在其他活动线程处于活动状态时,连续多次获取它
没有进展,当前没有锁定。
还要注意
untimed tryLock方法不支持公平性设置。会的
如果锁可用,即使其他线程正在等待,也会成功。
尝试熟悉ReentrantLock
的使用。公平性参数(您可以将其作为值传递给)是查看您的客户是否按照您希望的顺序得到服务的第一步。
这两种解决方案(另一个答案建议使用一个变量来控制顺序,尽管我不太喜欢,或者我的建议设置了一个公平性参数),然后反馈给我们更多的反馈
所以,正如您所看到的,服务队列受到了干扰
它没有被打扰。它实际上是按照你的设计工作的
ReentrantLock文档:
此类的构造函数接受可选的公平性参数。
如果设置为true,则在争用下,锁会优先授予对
最长-w