[英]Java Concurrency and Multithreading
这是一个很大的问题。
我试图在Java中创建一个有序的多生产者和单一消费者方案。 从某种意义上说,顺序是在生产者1之后,只有生产者2获得队列的控制权,之后是生产者3,之后是生产者1,依此类推。 只是为了检查在每种情况下是否都能奏效,我为三个制作人提供了三个不同的优先级
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 126
Producer1首先获得队列的控制权,然后是2,然后是3,然后又是1。
但是使用替代选项我得到了这个输出
2 6 8
2 6 8
2 6 8
同一生产者一直在控制队列。
除非等待的线程的索引与应该控制q的线程的索引匹配,否则不应该等待队列的控制,例如如果next为2,并且producer3被处理了对队列的控制,则不应它由于while条件而进入等待状态,并且队列又可以自由地被其他线程再次访问,该过程重复进行,直到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);
}
}
}
消费者
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);
}
}
}
考试班
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);
}
}
}
看起来您正在处理线程和并发,但是没有。
您正在处理逻辑运算符:
您的密码
while(flag==false && getIndex()!=next)
wait();
如果flag为true,则您的逻辑表达式为false,执行将继续。 您真正需要的是:
while(flag==false || getIndex()!=next)
wait();
此代码有很多错误,很难说出实际问题在哪里。 我强烈建议您先阅读一本有关该主题的好书,以提升对线程的了解。
这里的主要问题是您将线程优先级与执行顺序混淆了。 通常,线程的执行顺序是不确定的 ,除非您强制执行该顺序,否则没有顺序。 线程优先级唯一要做的就是指定正在运行的线程多于可以执行它们的CPU数量。 否则它将不执行任何执行顺序。
IE,当多个线程尝试输入同步功能时,将授予其中一个访问权限,但未指定将被指定的访问权限。 它可以是高优先级线程,但也可以是其他任何线程。 由于您的所有功能都已同步,因此所有线程始终处于暂停状态,因此即使线程优先级也无济于事,因为大多数时候线程无论如何都在等待其锁定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.