Connecting two threads in java - java

I have two classes that extends Thread. Class One, and class Two.
In my driver class, I create three threads of class One, and one hundred threads of class Two.
Each class One thread needs to notify every class Two thread that it's available to interact. After the two threads interact, the thread One moves on to another class Two thread that hasn't had an interaction with a class One thread.
How do I connect the two types of threads? How do I connect class 1 and class 2 threads. How does a thread using class 1 let every thread using class 2 know that it is available for interaction?
ex code:
public class Driver {
public static Semaphore sem = new Semaphore(1);
public static void main(String[] args) {
// TODO Auto-generated method stub
Teller tellerOne = new Teller(1);
Teller tellerTwo = new Teller(2);
Teller tellerThree = new Teller(3);
tellerOne.start();
tellerTwo.start();
tellerThree.start();
Client[] clients = new Client[10];
for(int i = 0; i<10; i++){
clients[i] = new Client(i);
clients[i].start();
}
System.out.println("Bank closes");
//end main method. do not write past this line
}
public class Teller extends Thread {
public int id;
public boolean bankOpen;
public Semaphore tsem;
Teller(int id){
this.id = id;
}
public void run(){
System.out.println("Teller " + id + " is available");
//end of run
}
//method to notify availability to client
public void notifyAvailabilityToClient(){
}
//end teller class, do not write past this line
public class Client extends Thread {
public int id;
public String status;
public Semaphore csem;
Client(int id){
this.id = id;
}
public void run(){
Random rand = new Random();
int withdrawOrDeposit = rand.nextInt(100);
withdrawOrDeposit = withdrawOrDeposit%2;
//if wORd%2 = 0, withdraw, else deposit
if(withdrawOrDeposit==0){
status="Withdraw";
}
else{
status="Deposit";
}
System.out.println("Client " + id + " waits in line to make a " + status);
//end of run method, do not write past this
}
//method to select an open Teller
public void selectAvailableTeller(){
}
//end of client class, do not write past this line
Btw I can use classes: Semaphore and Threads

I would not normally write code in which different threads meet up with each other, but since this appears to be a homework assignment...
In my solution there would be a single, blocking queue. When a "teller" thread starts up, and each time it finishes "interacting" with a customer, it would put its self into the queue, and then wait for a new customer to start an interaction. The customers all would wait to take() a teller from the queue, and when they get one,... "interact" with it.
If it was not homework I would do something entirely different. I don't know why "customer" threads are a thing, but I don't see any use for "teller" threads at all. There might be some kind of limited-availability Teller objects, but they would not be threads. The customer threads could "interact" by simply calling Teller methods or, if necessary, by submitting tasks that call Teller methods to a generic thread pool.

Related

What is the correct way to avoid an empty synchronized block?

Recently I've started looking into multithreading, and I have a question, perhaps more experienced ones could help.
My program creates two parallel threads, each of them prints counts from 0 to 19 (the NumbersPrinter class, which implements the Runnable interface).
class NumbersPrinter implements Runnable {
private Mediator mediator;
private String name;
private int makeActionOnCount;
public NumbersPrinter(Mediator mediator, String name, int makeActionOnCount) {
this.mediator = mediator;
this.name = name;
this.makeActionOnCount = makeActionOnCount;
}
#Override
public void run() {
for(int i = 0; i<20; i++){
try {
synchronized(this.mediator) {
if(this.mediator.actionInProgress.get()) {
System.out.println(name + " waits");
wait();
}
}
System.out.println(this.name + " says " + i);
Thread.sleep(500);
if(i == makeActionOnCount) {
synchronized(this.mediator) {
System.out.println(this.name + " asks Mediator to perform action...");
this.mediator.performAction();
this.mediator.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
When one of the threads reaches a certain number (defined in the makeActionOnCount variable), it starts performing a certain action that stops the execution of the second counter. The action lasts 5 seconds and after that both counters continue to count.
The counters are interconnected through an instance of the Mediator class, the performAcyion() method also belongs to the instance of the Mediator class.
import java.util.concurrent.atomic.AtomicBoolean;
class Mediator {
public AtomicBoolean actionInProgress = new AtomicBoolean(false);
public Mediator() {
}
public void performAction() throws InterruptedException {
actionInProgress.set(true);
System.out.println("Action is being performed");
Thread.sleep(5000);
System.out.println("Action has been performed");
actionInProgress.set(false);
}
}
Here's the Main class:
class Main {
public static void main(String[] args) throws InterruptedException{
Mediator mediator = new Mediator();
NumbersPrinter data = new NumbersPrinter(mediator, "Data", 10);
NumbersPrinter lore = new NumbersPrinter(mediator, "Lore", 5);
Thread oneThread = new Thread(data);
Thread twoThread = new Thread(lore);
System.out.println("Program started");
oneThread.start();
twoThread.start();
oneThread.join();
twoThread.join();
System.out.println("Program ended");
}
The way the program is written now - works fine, but I don't quite understand what exactly should I write in the first synchronized block, because if you delete all content from it, the program still works, since the counter that does not execute the performAction() method stops 'cause the counter cannot access the monitor of the Mediator object 'cause it is busy with the parallel counter. AtomicBoolean variable and checking it also makes no sense.
In other words, I may not use the wait () and notify () constructs at all, as well as the value of the AtomicBoolean variable, and just check access to the Mediator object's monitor every new iteration using an empty synchronized block. But I've heard that an empty synchronized block is a bad practice.
I am asking for help on how to rewrite the program to use the synchronized block and the wait() and notify() methods correctly.
Maybe I'm syncing on the wrong object? How would you solve a similar problem?
Thanks in advance

Communication between two threads created by a main thread in Java

So I have to create three Teller threads, and 100 Client threads.
Each thread must follow a sequence of actions, printing a record of each action.
the Teller threads must: notify the client that its available, accept id and transaction from a client, respond to client, .. and so on
the client has a similar set of actions: wait in line, when signaled select a free teller, etc
What I don't understand is, how do I get these threads to communicate?
So I make three Teller threads from the main method, 100 client threads, how exactly do I connect a client thread to a teller thread? Obviously when the three teller threads open, they can only take 3 clients, so 97 other client threads will be waiting. How do I stop the Client's run() method so the threads are still alive while waiting for an open Teller?
You can use a Count Down Latch.
Basically it works like this:
Count down latch signal helps by making client wait if all tellers are busy at the moment and notifies client thread if signal's count reaches 0 ( which means it's my turn).
My suggestion is, create a count down latch signal with count equal to 1 for each client and store them in a data structure(I recommend a queue), so everytime a teller is done with a client just pop a count down latch signal from the queue, then decrease popped signal's count to 0, so the client with this signal gets notified.
I recommend a queue because after every pop it deletes the element, so there are no any data races ( thread's reading the same element at the same time, which makes a client be served by two threads ).
I hope this helps.
Exchanging data between classes is done via class methods.
Likewise, exchanging messages between Threads is done via class methods.
If everything is local, ie you don't have to send anything over an online network, then you can try the following code:
import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;
import java.util.Random;
public class Main {
public static class MessageSource {
}
public static class Message<S extends MessageSource> {
private final S origin;
public Message(final S origin) {
this.origin = Objects.requireNonNull(origin);
}
public S getOrigin() {
return origin;
}
}
public static class ClientRequest extends Message<Client> {
public ClientRequest(final Client origin) {
super(origin);
}
}
public static class TellerResponse extends Message<Teller> {
public TellerResponse(final Teller origin) {
super(origin);
}
}
public static class Teller extends MessageSource implements Runnable {
private final Queue<ClientRequest> sharedQueue;
public Teller(final Queue<ClientRequest> sharedQueue) {
this.sharedQueue = Objects.requireNonNull(sharedQueue);
}
#Override
public void run() {
try {
final Random rand = new Random();
while (true) {
final ClientRequest r;
synchronized (sharedQueue) {
while (sharedQueue.isEmpty()) {
System.out.println("Teller " + hashCode() + " says queue is empty.");
sharedQueue.wait();
}
r = sharedQueue.poll();
}
System.out.println("Teller " + hashCode() + " currently seving request from Client " + r.getOrigin().hashCode() + "...");
Thread.sleep(250 + rand.nextInt(250)); //Delay a bit, to simulate serving the request and creating the response...
r.getOrigin().response(new TellerResponse(this)); //One could say that this simulates an RPC call :P
}
}
catch (final InterruptedException ix) {
System.err.println("Teller " + hashCode() + " stopped serving clients abruptly: " + ix);
}
}
}
public static class Client extends MessageSource implements Runnable {
private final Queue<ClientRequest> sharedQueue;
private TellerResponse privateQueue; //Since responses will be received here, I call this a queue (although it's not, because we know we can serve only one response at a time).
public Client(final Queue<ClientRequest> sharedQueue) {
this.sharedQueue = Objects.requireNonNull(sharedQueue);
}
public synchronized void response(final TellerResponse r) {
privateQueue = r;
notifyAll(); //Could be notify(). No difference would it make in this specific case.
}
#Override
public void run() {
//I'm just implementing random count of random-data requests...
final Random rand = new Random();
final int numberOfRequests = 5 + rand.nextInt(6);
try {
for (int i = 0; i < numberOfRequests; ++i) {
final ClientRequest req = new ClientRequest(this);
synchronized (sharedQueue) {
sharedQueue.add(req);
sharedQueue.notifyAll(); //Could be notify(). No difference would it make in this specific case.
}
synchronized (this) {
while (privateQueue == null)
wait();
System.out.println("Client " + hashCode() + " can consume the " + privateQueue.getOrigin().hashCode() + " Teller's response...");
privateQueue = null;
}
}
}
catch (final InterruptedException ix) {
System.err.println("Client " + hashCode() + " stopped receiving responses abruptly: " + ix);
}
}
}
public static void main(final String[] args) {
final Queue<ClientRequest> requests = new LinkedList<>();
for (int i = 0; i < 100; ++i)
new Thread(new Client(requests)).start();
for (int i = 0; i < 3; ++i)
new Thread(new Teller(requests)).start();
}
}
A single ClientRequest is answered by a Teller with a single TellerResponse.
Now you have to extend the classes ClientRequest and TellerResponse according to your needs (ie implement what data should be exchanged).
This implementation is a producer-consumer pattern where both the Tellers and the Clients are both producers and consumers.
This implementation uses a shared queue to exchange messages from clients to tellers.
There is no stopping condition for the tellers (which makes them wait indefinetly at the end of the clients' requests) which will make the program wait forever at the end of the clients' requests.
But this is expected since we have no terminating condition.
The clients will run creating from 5 up to 10 requests. The tellers will delay each response from 250 to 500ms. With 3 tellers and 100 clients, that makes us about from 42 up to 167 seconds runtime.
A more reallistic communication approach I guess would use PipedInputStreams and PipedOutputStreams to simulate traffic over blocking streams (such as network traffic).

Java multi threading - run threads run method only once in sequence

In my applications there are an n number of actions that must happen, one after the other in sequence, for the whole life of the program. Instead of creating methods which implement those actions and calling them in order in a while(true) loop, I decided to create one thread for each action, and make them execute their run method once, then wait until all the other threads have done the same, wait for its turn, and re-execute again, and so on...
To implement this mechanism I created a class called StatusHolder, which has a single field called threadTurn (which signifies which thread should execute), a method to read this value, and one for updating it. (Note, this class uses the Singleton design pattern)
package Test;
public class StatusHolder
{
private static volatile StatusHolder statusHolderInstance = null;
public static volatile int threadTurn = 0;
public synchronized static int getTurn()
{
return threadTurn;
}
public synchronized static void nextTurn()
{
System.out.print("Thread turn: " + threadTurn + " --> ");
if (threadTurn == 1)
{
threadTurn = 0;
}
else
{
threadTurn++;
}
System.out.println(threadTurn);
//Wake up all Threads waiting on this obj for the right turn to come
synchronized (getStatusHolder())
{
getStatusHolder().notifyAll();
}
}
public static synchronized StatusHolder getStatusHolder()
{//Returns reference to this object
if (statusHolderInstance == null)
{
statusHolderInstance = new StatusHolder();
}
return statusHolderInstance;
}
}
Then I have, let's say, two threads which must be execute in the way explained above, t1 and t2.
T1 class looks like this:
package Test;
public class ThreadOne implements Runnable
{
#Override
public void run()
{
while (true)
{
ThreadUtils.waitForTurn(0);
//Execute job, code's not here for simplicity
System.out.println("T1 executed");
StatusHolder.nextTurn();
}
}
}
And T2 its the same, just change 0 to 1 in waitForTurn(0) and T1 to T2 in the print statement.
And my main is the following:
package Test;
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Thread t1 = new Thread(new ThreadOne());
Thread t2 = new Thread(new ThreadTwo());
t1.start();
t2.start();
}
}
So the run method goes like this:
At the start of the loop the thread looks if it can act by checking the turn value with the waitForTurn() call:
package Test;
public class ThreadUtils
{
public static void waitForTurn(int codeNumber)
{ //Wait until turn value is equal to the given number
synchronized (StatusHolder.getStatusHolder())
{
while (StatusHolder.getTurn() != codeNumber)
{
try
{
StatusHolder.getStatusHolder().wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
If the two values are equal, the thread executes, otherwise it waits on the StatusHolder object to be awaken from the nextTurn() call, because when the turn value changes all the threads are awaken so that they can check if the new turn value is the one they are waiting for so they can run.
Note thatnextTurn() cycles between 0 and 1: that is because in this scenario I just have two threads, the first executes when the turn flag is 0, and the second when its 1, and then 0 again and so on. I can easily change the number of turns by changing this value.
The problem: If I run it, all goes well and seems to work, but suddenly the output console stops flowing, even if the program doesn't crash at all. I tried to put a t1.join() and then a print in the main but that print never executes, this means that the threads never stop/dies, but instead they remain locked sometimes.
This looks to be even more evident if I put three threads: it stops even sooner than with two threads.
I'm relatively new to threads, so I might be missing something really stupid here...
EDIT: I'd prefer not to delete a thread and create a new one every time: creating and deleting thousands of objs every second seems a big work load for the garbage collector.
The reason why I'm using threads and not functions is because in my real application (this code is just simplified) at a certain turn there actually are multiple threads that must run (in parallel), for example: turn 1 one thread, turn 2 one thread, turn 3 30 threads, repeat. So I thought why not creating threads also for the single functions and make the whole think sequential.
This is a bad approach. Multiple threads allow you to execute tasks concurrently. Executing actions "one after the other in sequence" is a job for a single thread.
Just do something like this:
List<Runnable> tasks = new ArrayList<>();
tasks.add(new ThreadOne()); /* Pick better names for tasks */
tasks.add(new ThreadTwo());
...
ExecutorService worker = Executors.newSingleThreadExecutor();
worker.submit(() -> {
while (!Thread.interrupted())
tasks.forEach(Runnable::run);
});
worker.shutdown();
Call worker.shutdownNow() when your application is cleanly exiting to stop these tasks at the end of their cycle.
you can use Semaphore class it's more simple
class t1 :
public class t1 implements Runnable{
private Semaphore s2;
private Semaphore s1;
public t1(Semaphore s1,Semaphore s2){
this.s1=s1;
this.s2=s2;
}
public void run()
{
while (true)
{
try {
s1.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(t1.class.getName()).log(Level.SEVERE, null, ex);
}
//Execute job, code's not here for simplicity
System.out.println("T1 executed");
s2.release();
}
}
}
class t2:
public class t2 implements Runnable{
private Semaphore s2;
private Semaphore s1;
public t2(Semaphore s1,Semaphore s2){
this.s1=s1;
this.s2=s2;
}
public void run()
{
while (true)
{
try {
s2.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(t2.class.getName()).log(Level.SEVERE, null, ex);
}
//Execute job, code's not here for simplicity
System.out.println("T2 executed");
s1.release();
}
}
}
class main:
public class Testing {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Semaphore s2=new Semaphore(0);
Semaphore s1=new Semaphore(1);
Thread th1 = new Thread(new t1(s1,s2));
Thread th2 = new Thread(new t2(s1,s2));
th1.start();
th2.start();
}}

Executing threads in a Threadgroup serially in Java

I am currently learning basics of Threads in Java and I am trying to write a program simulating a 2x200 Relay race with 2 teams. I would like to have 2 teams (represented by a ThreadGroup each) and each team has 2 members, each of which must run for 200 m. Here running is just simulated by looping in a for loop and printing. I am not able to find a straight forward way of running threads in a Threadgroup in serially
Here is how the worker looks like
public class RelayRunner implements Runnable {
#Override
public void run() {
for (int i = 1; i <= 200; i++) {
String name = Thread.currentThread().getName();
if (i % 50 == 0) {
System.out.format("%s ran %d m \n", name, i);
}
}
}
}
Here is how the main program looks like
public class RelayRunnerMatch {
public static void main(String[] args) {
RelayRunner relayRunner = new RelayRunner();
ThreadGroup usa = new ThreadGroup("USA");
ThreadGroup germany = new ThreadGroup("GERMANY");
Thread usa1 = new Thread(usa, relayRunner, "usa1");
Thread germany1 = new Thread(germany, relayRunner, "germany1");
Thread usa2 = new Thread(usa, relayRunner, "usa2");
Thread germany2 = new Thread(germany, relayRunner, "germany2");
usa1.start();
germany1.start();
/* Now I would like to start the second thread in a group only if the first
thread in the same group has finished like in a real relay race. How??
*/
//usa1.join(); germany1.join();
//usa2.start(); germany2.start() --> Not good, usa2 must start immediately when usa1 has finished
}
}
I am not able to see how the join() may be of any help here as it will wait for both threads to finish before the second set of runners can start their run. Also I realize that activeCount() is just an estimate, so I am not sure of using that either.
Is there a solution possible without resorting to services in new Concurrent API(as I haven't reached that further)?
public class Player1 implements Runnable{
private final CountDownLatch countDownLatch;
private final String s;
public Player1(CountDownLatch c, String s){
this.countDownLatch=c;
this.s=s;
}
#Override
public void run() {
for(int i=0;i<200;i++){
System.out.println(s+":"+i);
}
countDownLatch.countDown();
}
}
public class Player2 implements Runnable{
private final CountDownLatch countDownLatch;
private final String s;
public Player2(CountDownLatch c, String s){
this.countDownLatch = c;
this.s=s;
}
#Override
public void run() {
try {
countDownLatch.await();
} catch (InterruptedException ex) {
Logger.getLogger(Player2.class.getName()).log(Level.SEVERE, null, ex);
}
for(int i=0;i<200;i++){
System.out.println(s+":"+i);
}
}
}
Driver program:
public static void main(String[] args){
Thread[] grp1 = new Thread[2];
Thread[] grp2 = new Thread[2];
CountDownLatch c1 = new CountDownLatch(1);
CountDownLatch c2 = new CountDownLatch(1);
grp1[0]=new Thread(new Player1(c1, "grp1:player1"));
grp1[1]=new Thread(new Player2(c2, "grp1:player2"));
grp2[0]=new Thread(new Player1(c2, "grp2:player1"));
grp2[1]=new Thread(new Player2(c2, "grp2:player2"));
grp1[0].start();
grp2[0].start();
grp1[1].start();
grp2[1].start();
}
You could create two baton-objects and synchronize on the respective baton so the second thread would have to wait until the first one releases the baton - or use some locks from java.util.concurrent.locks-package to achieve the same. But your relay-members will compete in who gets the baton first or next and you can't define some real order.
But as Jarrod said: when you have several tasks that have to be executed sequentially you better execute them on the same thread: have some runner-objects and add them to a queue on the respective relay-thread that calls their run-method one after the other.

String literal synchronization

I'm trying to synchronize a String literal, so that I can control the execution of my threads but for some reason that does not work..
Is there any problem with the way its synchronized?
package scratch1;
public class OrderedThread {
public static void main(String[] args){
RunThread first, second, third;
OrderedThread orderedthread = new OrderedThread();
first = new RunThread("One",orderedthread);
second = new RunThread("Two",orderedthread);
third = new RunThread("Three",orderedthread);
second.start();
first.start();
third.start();
}
public void display(String msg){
synchronized(msg){
for (int i = 1; i <= 20; i++){
System.out.println("Name = "+ msg);
}
}
}
}
class RunThread extends Thread{
String name;
OrderedThread orderT;
RunThread(String name, OrderedThread orderT){
this.name = name;
this.orderT = orderT;
}
public void run(){
orderT.display(name);
}
}
The point of synchronization is access to shared resources. Your thread is supposed to acquire the monitor on an object that other threads are trying to access. In your case, each thread acquires a different object's monitor, so none of them blocks.
If instead you passed the literal "One" to your constructors
first = new RunThread("One",orderedthread);
second = new RunThread("One",orderedthread);
third = new RunThread("One",orderedthread);
Then you would see execution in order. Each thread would have to finish its for-loop (inside the synchronized block) before another one can start. This is because each Thread is synchronized on the same String object.
Better yet, use one of them many java.util.concurrent classes that act as locks. For example, Lock.

Categories