I've made three classes and I use one of them to create and start two separate threads for other two classes. How can I pass values within those two classes?
Asked
Active
Viewed 97 times
-2
-
Using constructor for example. – Sergey Prokofiev Apr 18 '18 at 05:44
-
3So, you're basically describing a "produce/consumer" paradigm. The basic concept would use some kind of blocking queue to send information between the first class (producer) to the other classes (consumers) - how exactly, would depend largely on what you are trying to achieve – MadProgrammer Apr 18 '18 at 05:45
1 Answers
2
I would suggest using a LinkedTransferQueue from the java.util.concurrent
package. Each thread would have a queue which would serve as an inbox for messages from the other threads, and could take()
messages from it to act on, and transfer()
messages into the mailboxes of the other threads.
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
class Leader implements Runnable {
private final Follower follower;
private final TransferQueue<String> queue = new LinkedTransferQueue<>();
public Leader(Follower follower) {
this.follower = follower;
}
public void sendMessage(String message) throws InterruptedException {
queue.transfer(message);
}
public void run() {
try {
follower.sendMessage("WAKE UP, SLEEPYHEAD!");
while (true) {
String message = queue.take();
if (message.equals("STOP")) {
break;
} else {
follower.sendMessage("SAY " + message);
}
}
System.out.println("Exiting");
} catch (Exception e) {
// we're exiting anyway, let it go
}
}
}
class Follower implements Runnable {
private final TransferQueue<String> queue = new LinkedTransferQueue<>();
public void sendMessage(String message) throws InterruptedException {
queue.transfer(message);
}
public void run() {
try {
while (true) {
String message = queue.take();
if (message.equals("STOP")) {
break;
} else if (message.startsWith("SAY ")) {
System.out.println(message.substring(4));
} else {
System.out.println("My leader gave me a message I don't understand.");
}
}
System.out.println("I've been told to stop.");
} catch (Exception e) {
// we're exiting anyway, let it go
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Follower follower = new Follower();
Leader leader = new Leader(follower);
Thread one = new Thread(leader);
Thread two = new Thread(follower);
// start the follower first
two.start();
one.start();
// tell the leader, and the leader will tell the follower
leader.sendMessage("Hello, world");
leader.sendMessage("Good-bye");
leader.sendMessage("STOP");
follower.sendMessage("STOP");
one.join();
two.join();
System.out.println("Be seeing you.");
}
}
If you don't want the thread performing the transfer to wait until the message is received before it proceeds, you can use a LinkedBlockingQueue
instead, but it can be surprising when threads get ahead of one another and messages are perceived to be received "out of order." However, in the case of truly asynchronous code, that can be exactly what you want.
I stuck with the more intuitive TransferQueue in this example.

OldCurmudgeon
- 64,482
- 16
- 119
- 213

David Conrad
- 15,432
- 2
- 42
- 54