Java并发和多线程
这是一个很大的问题 我试图用Java创建一个有序的多生产者和单消费者场景。排序的意义是,在producer1之后,只有producer2获得队列的控制权,之后是producer3,之后是producer1,依此类推。为了检查这是否在每种情况下都有效,我向三位制作人提供了三种不同的优先级 producer1-Thread.NORM_优先级-4 producer2-Thread.NORM_优先级+5 producer3-Thread.NORM\u优先级 现在,我不再打印队列中的内容和消耗的内容,而是保留一个计数器来计算每个生产者线程被交给队列控制的次数和顺序,并在消费者线程中打印这些计数 代码在输出之后提供。 我对线程的一个特殊行为感到困惑,下面发布的代码按我所希望的那样工作,但是如果我替换它Java并发和多线程,java,multithreading,concurrency,Java,Multithreading,Concurrency,这是一个很大的问题 我试图用Java创建一个有序的多生产者和单消费者场景。排序的意义是,在producer1之后,只有producer2获得队列的控制权,之后是producer3,之后是producer1,依此类推。为了检查这是否在每种情况下都有效,我向三位制作人提供了三种不同的优先级 producer1-Thread.NORM_优先级-4 producer2-Thread.NORM_优先级+5 producer3-Thread.NORM\u优先级 现在,我不再打印队列中的内容和消耗的内容,而是
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);
}
}
}
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);
}
}
}
看起来您正在处理线程和并发,但不是 您正在处理逻辑运算符: 你的代码
while(flag==false && getIndex()!=next)
wait();
如果flag为true,那么逻辑表达式将为false,执行将继续。您真正需要的是:
while(flag==false || getIndex()!=next)
wait();
看起来您正在处理线程和并发,但不是 您正在处理逻辑运算符: 你的代码
while(flag==false && getIndex()!=next)
wait();
如果flag为true,那么逻辑表达式将为false,执行将继续。您真正需要的是:
while(flag==false || getIndex()!=next)
wait();
这段代码有太多错误,很难判断实际问题在哪里。我强烈建议你先读一本关于线程的好书来提升你的知识 这里的主要问题是混淆了线程优先级和执行顺序。通常,线程的执行顺序是未定义的,除非您强制执行该顺序,否则没有顺序。线程优先级所做的唯一一件事是,如果运行的线程多于可以执行它们的CPU,那么指定哪个线程被搁置。否则,它不会执行任何执行命令
也就是说,当几个线程试图进入一个同步函数时,其中一个线程被授予访问权限,但没有指定哪个线程将被访问。它可以是高优先级线程,但也可以是任何其他线程。由于所有函数都是同步的,所以所有线程都会一直处于暂停状态,因此即使线程优先级也不会起作用,因为大多数时间线程都在等待它们的锁。这段代码有很多错误,很难判断实际问题出在哪里。我强烈建议你先读一本关于线程的好书来提升你的知识 这里的主要问题是混淆了线程优先级和执行顺序。通常,线程的执行顺序是未定义的,除非您强制执行该顺序,否则没有顺序。线程优先级所做的唯一一件事是,如果运行的线程多于可以执行它们的CPU,那么指定哪个线程被搁置。否则,它不会执行任何执行命令
也就是说,当几个线程试图进入一个同步函数时,其中一个线程被授予访问权限,但没有指定哪个线程将被访问。它可以是高优先级线程,但也可以是任何其他线程。由于您的所有函数都是同步的,所以所有线程都会一直处于暂停状态,因此即使是线程优先级也不会起作用,因为大多数时间线程都在等待它们的锁。如果希望生产者按顺序工作,为什么要使用线程?它实际上是更大应用程序的一部分,这只是一个线程必须按顺序工作的问题场景。你打算如何关闭程序?嗨,Jim,就像我提到的,这是一个测试场景,我只想测试一个特定的逻辑,现在我手动关闭代码,但在我希望它工作的应用程序中,线程关闭,一旦他们获得对队列的特定次数的访问权。如果你想让生产者按顺序工作,为什么要使用线程?这实际上是一个更大的应用程序的一部分,这只是一个线程必须按顺序工作的问题场景。你打算如何关闭程序?嗨,Jim,就像我提到的,这是一个测试场景,我只是想测试一个特定的逻辑,现在我正在手动关闭代码,但在我希望它工作的应用程序中,一旦线程访问队列特定次数,线程就会关闭。是的,线程优先级不能保证线程何时访问锁,但是,如果n个线程正在等待某个特定的同步方法,则优先级较高的线程更有可能访问该方法,而不是优先级较低的线程。我的问题的全部目的是消除这种情况,并以预先指定的顺序访问线程,而不管它们的优先级如何