如何让java中的线程读取两个独立线程的值
嗯。我需要做三个线程:一个获取奇数,一个获取偶数,一个将奇数和偶数相加。输出应该是这样的(1,2,3,3,4,7…)。 我是线程新手,对线程的工作方式仍不确定,但到目前为止,我已经做到了:如何让java中的线程读取两个独立线程的值,java,multithreading,Java,Multithreading,嗯。我需要做三个线程:一个获取奇数,一个获取偶数,一个将奇数和偶数相加。输出应该是这样的(1,2,3,3,4,7…)。 我是线程新手,对线程的工作方式仍不确定,但到目前为止,我已经做到了: class even extends Thread { public void even() { Thread ThreadEven = new Thread(this); start(); } public void run()
class even extends Thread
{
public void even()
{
Thread ThreadEven = new Thread(this);
start();
}
public void run()
{
try
{
for(int i = 0; i < 10; i += 2)
{
System.out.println(i);
}
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("Error: Thread Interrupted");
}
}
}
class odd extends Thread
{
public void odd()
{
Thread ThreadOdd = new Thread(this);
start();
}
public void run()
{
try
{
for(int i = 1;i < 10; i += 2)
System.out.println(i);
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("Error: Thread Interrupted");
}
}
}
class ThreadEvenOdd
{
public static void main(String args [])
{
even e = new even();
odd o = new odd();
}
}
类甚至扩展了线程
{
公共空间
{
螺纹偶数=新螺纹(此);
start();
}
公开募捐
{
尝试
{
对于(int i=0;i<10;i+=2)
{
系统输出打印LN(i);
}
睡眠(1000);
}
捕获(例外e)
{
System.out.println(“错误:线程中断”);
}
}
}
类奇数扩展线程
{
公共空间(奇数)
{
螺纹奇数=新螺纹(此);
start();
}
公开募捐
{
尝试
{
对于(int i=1;i<10;i+=2)
系统输出打印LN(i);
睡眠(1000);
}
捕获(例外e)
{
System.out.println(“错误:线程中断”);
}
}
}
奇数类
{
公共静态void main(字符串参数[])
{
偶数e=新偶数();
奇数o=新的奇数();
}
}
这会打印出0,2,4…然后是1,3,5。
如何交织?交错是我想要的吗?我应该同步线程吗?
我不明白的是如何将奇数和偶数线程的值放入第三个线程中,以相加和。
如果代码的格式不正确,请提前道歉。如前所述,这是一个高级问题,是的,在尝试此操作之前,您应该阅读大量教程。即使对于这个简短的程序,如果我没有花很多时间仔细研究的话,我也不可能写出来。(提示-买这本书,都在里面。) 类偶数和奇数是生产者。类总和是消费者。生产者和消费者共享一个阻塞队列来传递数据。生产商使用负数作为毒丸,以表明他们已经完成,不会有更多的数据。当消费者检测到毒丸时,它会减少倒计时闩锁。主线程将此作为工作完成的信号
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
public class OddEven
{
public static void main(String [] args) throws InterruptedException
{
BlockingQueue<Integer> evens = new ArrayBlockingQueue<Integer>(1);
BlockingQueue<Integer> odds = new ArrayBlockingQueue<Integer>(1);
even e = new even(evens);
odd o = new odd(odds);
sum s = new sum(evens, odds);
e.start();
o.start();
s.start();
s.waitUntilDone();
}
}
class sum extends Thread
{
private final BlockingQueue<Integer> in1;
private final BlockingQueue<Integer> in2;
private final CountDownLatch done = new CountDownLatch(1);
public sum(BlockingQueue<Integer> in1, BlockingQueue<Integer> in2)
{
this.in1 = in1;
this.in2 = in2;
}
public void waitUntilDone() throws InterruptedException
{
done.await();
}
public void run()
{
try
{
while (true)
{
int a = in1.take();
int b = in2.take();
if (a == -1 && b == -1)
break;
int c = a + b;
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
done.countDown();
}
catch(Exception e)
{
System.out.println("Error: Thread Interrupted");
}
}
}
class even extends Thread
{
private final BlockingQueue<Integer> out;
public even(BlockingQueue<Integer> out)
{
this.out = out;
}
public void run()
{
try
{
for(int i = 0; i < 10; i += 2)
out.put(i);
out.put(-1);
}
catch(Exception e)
{
System.out.println("Error: Thread Interrupted");
}
}
}
class odd extends Thread
{
private final BlockingQueue<Integer> out;
public odd(BlockingQueue<Integer> out)
{
this.out = out;
}
public void run()
{
try
{
for(int i = 1;i < 10; i += 2)
out.put(i);
out.put(-1);
}
catch(Exception e)
{
System.out.println("Error: Thread Interrupted");
}
}
}
您需要一种将数字从生产者线程(偶数和奇数)传递到“消费者”线程的方法
“最简单”但不是最好的方法是一个可变数组,只有一个条目——您必须同步/锁定某个对象(数组?),以避免并发线程破坏它
也许更简单、更好的方法是使用“双端队列”,如ArrayQueue。这样可以将值放在一端,然后从另一端删除。同样,对它的访问需要同步
在所有线程外部创建队列,然后将其传入/或使其可见
class Example {
protected Deque<Integer> queueEven = new ArrayDeque<Integer>();
protected Deque<Integer> queueOdd = new ArrayDeque<Integer>();
// you can synchronize on some mutable flag to finish, too.
class Even extends Thread {
public void run() {
for (int i = 0; i < 10; i += 2) {
synchronized (queueEven) {
queueEven.add( i);
}
}
}
}
class Odd extends Thread {
public void run() {
for (int i = 1; i < 10; i += 2) {
synchronized (queueOdd) {
queueOdd.add( i);
}
}
}
}
class AddEvenOdd extends Thread {
public void run() {
while (true) {
int even;
synchronized (queueEven) {
even = queueEven.removeFirst();
}
int odd;
synchronized (queueOdd) {
odd = queueOdd.removeFirst();
}
int result = even + odd;
System.out.println("result="+result);
}
}
}
}
类示例{
受保护的Deque queue偶数=新的ArrayDeque();
protected Deque queueOdd=new ArrayDeque();
//您也可以在某个可变标志上进行同步以完成。
类甚至扩展了线程{
公开募捐{
对于(int i=0;i<10;i+=2){
已同步(排队偶数){
加入(i);
}
}
}
}
类奇数扩展线程{
公开募捐{
对于(int i=1;i<10;i+=2){
已同步(奇数){
加入(i);
}
}
}
}
类AddEventOdd扩展线程{
公开募捐{
while(true){
整数偶数;
已同步(排队偶数){
偶数=Queue偶数。removeFirst();
}
int奇数;
已同步(奇数){
奇数=queueOdd.removeFirst();
}
int结果=偶数+奇数;
System.out.println(“结果=”+结果);
}
}
}
}
请花些时间重新格式化代码。现在很难读懂。请参阅:另外,在对象构造函数中,您不应该泄漏this
。这就建立了即时的比赛条件。请参阅:“如果我没有获得代码的正确格式,请事先道歉。”-说真的,如果你知道格式不好,在你点击“发布问题”按钮之前修复此问题会更尊重读者。它仍然是一团混乱。将所有“制表符”字符替换为空格。在这两个类中,您都在构造一个新的线程
,然后立即将其丢弃。然后从构造函数调用start()
。你的类是一个线程
;你把它延长了。你不应该那样调用start()
。在进一步讨论之前,我真的建议您阅读关于线程(可能还有基本java)的Oracle教程。谢谢。很好的解释。真的,真的很感激。我也要去拿那本书。我也是一个纯C/C++背景的人,很难理解Java。特别是线程。我喜欢这些“生产者”和“消费者”的术语。当我试图学习线程时,这更有意义。通过这两个示例,我可以看到线程的深度。看来这些排队是必要的
class Example {
protected Deque<Integer> queueEven = new ArrayDeque<Integer>();
protected Deque<Integer> queueOdd = new ArrayDeque<Integer>();
// you can synchronize on some mutable flag to finish, too.
class Even extends Thread {
public void run() {
for (int i = 0; i < 10; i += 2) {
synchronized (queueEven) {
queueEven.add( i);
}
}
}
}
class Odd extends Thread {
public void run() {
for (int i = 1; i < 10; i += 2) {
synchronized (queueOdd) {
queueOdd.add( i);
}
}
}
}
class AddEvenOdd extends Thread {
public void run() {
while (true) {
int even;
synchronized (queueEven) {
even = queueEven.removeFirst();
}
int odd;
synchronized (queueOdd) {
odd = queueOdd.removeFirst();
}
int result = even + odd;
System.out.println("result="+result);
}
}
}
}