这是个大问题。
我试图在Java中创建一个有序的多生产者和单一消费者场景。从这个意义上说,在producer1之后,只有producer2才能控制队列,然后是producer3,然后是producer1等等。为了检查这在每一种情况下是否有效,我为三位制作人提供了三个不同的优先事项。
producer1 - Thread.NORM_PRIORITY -4
producer2 - Thread.NORM_PRIORITY +5
producer3 - Thread.NORM_PRIORITY
现在,我没有打印队列中的内容和正在使用的内容,而是保留一个计数器来计算每个生产者线程被传递多少次控制队列和顺序,并在使用者线程中打印这些计数。
在输出后提供代码。我对线程的一种特殊行为感到困惑,下面发布的代码按我的意愿工作,但如果我替换它
while(flag==false)
wait();
if(getIndex()!=next)
return;在q.java的put()函数中,使用如下
while(flag==false && getIndex()!=next)
wait();生产者线程被不稳定地传递给队列的控制。与第一个代码片段一样,我得到了下面的输出,分别用于生产者1、2和3
125 125 125
126 125 125
126 126 125
126 126 126Producer1首先控制队列,然后是2,然后是3,然后是1。
但是有了另一种选择,我得到了这个输出
2 6 8
2 6 8
2 6 8同一个生产者一直在控制队列。
除非等待线程的索引与线程的索引匹配,否则等待线程不应该获得队列的控制,就像next是2,而producer3是对队列的控制,是不是应该因为which条件而进入等待,并且队列可以被其他线程再次自由地接近,进程会重复直到producer2得到它?
队列
import java.util.*;
class q
{
private volatile int size;
private volatile int clicks[];
private volatile boolean flag;
private volatile int next;
public q(int size)
{
this.size = size;
clicks = new int[size+1];
flag = true;
next = 1;
}
private synchronized int getIndex()
{
String name = Thread.currentThread().getName();
return (int)(name.charAt(name.length()-1))-48;
}
private synchronized void show()
{
//System.out.println("Got control -> "+name+" for index "+index);
if(flag==true)
{
int index = getIndex();
/*
System.out.println("Control provided to "+index);
Scanner s = new Scanner(System.in);
System.out.println("Press enter to continue");
String c = s.next();
*/
clicks[index]+=1;
next = (index%size)+1;
//System.out.println("Provide control to "+next);
}
else
{
int i;
for(i = 1;i<=size;i++)
System.out.print(clicks[i]+" ");
System.out.println();
}
}
public synchronized void put()
{
try
{
while(flag==false)
wait();
if(getIndex()!=next)
return;
show();
flag = false;
notify();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
public synchronized void get()
{
try
{
while(flag==true)
wait();
show();
flag = true;
notifyAll();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}生产者
class producer implements Runnable
{
private q queue;
public producer(q queue)
{
this.queue = queue;
}
public void run()
{
try
{
//int i;
while(true)
queue.put();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}CONSUMER
class consumer implements Runnable
{
private q queue;
public consumer(q queue)
{
this.queue = queue;
}
public void run()
{
try
{
while(true)
queue.get();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}TESTCLASS
class testclass
{
private q queue;
private producer p1; //lowest priority
private producer p2; //highest priority
private producer p3; //normal priority
private consumer c;
private Thread pt1;
private Thread pt2;
private Thread pt3;
private Thread ct;
public testclass()
{
queue = new q(3);
p1 = new producer(queue);
p2 = new producer(queue);
p3 = new producer(queue);
c = new consumer(queue);
pt1 = new Thread(p1,"producer1");
pt2 = new Thread(p2,"producer2");
pt3 = new Thread(p3,"producer3");
ct = new Thread(c,"consumer");
}
public void begin()
{
pt2.setPriority(Thread.NORM_PRIORITY + 5);
pt1.setPriority(Thread.NORM_PRIORITY - 4);
//pt3.setPriority(Thread.NORM_PRIORITY - 3);
pt1.start();
pt2.start();
pt3.start();
ct.start();
}
public static void main(String args[])
{
try
{
testclass t = new testclass();
t.begin();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
} 发布于 2017-09-09 11:26:14
看起来您正在处理线程和并发性,但没有。
您正在处理的是逻辑运算符:
你的代码
while(flag==false && getIndex()!=next)
wait();如果标志为true,则逻辑表达式将为false,并且执行将继续进行。你真正需要的是:
while(flag==false || getIndex()!=next)
wait();发布于 2017-09-11 11:36:47
这个代码有太多的错误,很难判断实际的问题在哪里。我强烈建议你首先通过阅读一本关于线程的好书来提升你的线程知识。
这里的主要问题是您混淆了线程优先级和执行顺序。通常,线程的执行顺序是未定义的,除非强制执行该命令,否则就没有顺序。线程优先级所做的唯一一件事是,如果运行的线程多于可以执行线程的CPU,则指定哪个线程处于暂停状态。否则,它不会强制执行任何执行命令。
也就是说,当几个线程试图输入一个同步函数时,其中一个线程将被授予访问权,但是没有指定哪个线程。它可以是高优先级线程,但也可以是任何其他线程。由于您的所有函数都是同步的,所以所有线程都会被搁置,因此即使线程优先级也不会做任何事情,因为大多数时候线程都在等待它们的锁。
https://stackoverflow.com/questions/46129182
复制相似问题