How to serialize a code that is under synchronization? [duplicate] - java

This question already has answers here:
Should you synchronize the run method? Why or why not?
(6 answers)
Closed 7 years ago.
I need to create 2 classes, Class Player and Class Referee which implement Runnable interface(Basically, create threads).
The order in which the threads have to be executed are
Referee
Player 1 or 2
Referee
Player 1 or 2
and so on..
Here, is the solution that I came up with, but, the order doesn't seem to happen. Players keep playing even before referee completes checking.
``
public class a {
public static synchronized void main(String[] args) throws InterruptedException {
ready = false;
finish = false;
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Referee());
executorService.execute(new Player(1));
executorService.execute(new Player(2));
Thread.sleep(1000);
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
}
/*....FOLLOWED BY GETTER AND SETTER METHODS
*
*
*/
}
class Player implements Runnable{
public synchronized void play() throws InterruptedException{
//continue playing unless game is over
while(true)
{
while( (a.getReady()) != true){
wait();
}
/***
*
*
*
execute some code to play
**/
//Change the value of the condition variable for the referee to start executing
a.putReady(false);
}
}
#Override
public void run() {
try {
play();
} catch (InterruptedException ex) {
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class Referee implements Runnable{
public synchronized void check() throws InterruptedException {
while(true)
{
/****INITIALIZING THE GAME***/
while(a.getReady())
wait();
//If some player has won, releasing locks and exiting the threads
if(winner != 0)
{
a.putReady(true);
a.putFinish(true);
return;
}
//If the boards are full and ends in a draw
else if(count_plays >= 42)
{
System.out.print("\n Board is full. Its a draw!!\n");
a.putReady(true);
a.putFinish(true);
return;
}
//If there is more space on the board to play
else
{
System.out.print("\nNo player has won, let the play resume!!\n");
//Thread.sleep((long)100);
}
/* Code for checking if there has been a winner
*
*
*/
a.putReady(true);
notify();
}
}
#Override
public void run(){
try {
check();
}
catch (InterruptedException ex) {
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
`
I understand that threads of different objects cannot be synchronized and there is no point in serializing the code that is under synchronization. This is a task that I have been assigned. In the above code, Players play simultaneously even after providing a set of condition variables and do not allow thread of the referee to check for the winner each time they play.
Please, give me an outline of the code to provide such an output using synchronized method, notify() and wait().

It is allowed but rarely makes sense and would not make sense in your case. The two threads would be synchronizing on different objects which would have no effect. The point of the synchronized method is to prevent two threads from simultaneously accessing the same object. If the two players need to access some common object but you don't want the accesses to overlap you should synchronize on that object or synchronize one of the methods of that object. You should only be within a synchronized block or method for as little time as possible. synchronizing unnecessarily can lead to poor performance or deadlock.
The closest that made any sense to me was this:
a
public static class a {
static boolean finish = false;
public static void main(String[] args) throws InterruptedException {
finish = false;
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Referee());
executorService.execute(new Player(1));
executorService.execute(new Player(2));
// wait for user to press enter, just for testing
new Scanner(System.in).nextLine();
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
}
}
Player
public class Player implements Runnable {
final int playernum;
public Player(int playernum) {
this.playernum = playernum;
}
#Override
public void run() {
try {
while (!a.finish) {
synchronized (a.class) {
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println("player " + playernum + " does step " + i);
}
}
Thread.sleep(1000);
}
} catch (InterruptedException interruptedException) {
}
}
}
Referee
public class Referee implements Runnable {
#Override
public void run() {
try {
while (!a.finish) {
synchronized (a.class) {
System.out.println("Check for winner.");
}
Thread.sleep(1000);
}
} catch (InterruptedException interruptedException) {
}
}
}
Notice that it is not synchronized during the entire run only during an internal block inside.
It should produce something like this:
Check for winner.
player 1 does step 0
player 1 does step 1
player 1 does step 2
player 1 does step 3
player 1 does step 4
Check for winner.
player 2 does step 0
player 2 does step 1
player 2 does step 2
player 2 does step 3
player 2 does step 4
Without synchronization you would not see all 5 steps from each player with no intervening checks or steps from the other player.

Related

Print alternately with three threads [duplicate]

I am trying to print numbers from 1 to 10 using three threads. thread 1 prints 1, 2 prints 2, 3 prints 3, 4 is printed by thread 1 again and so on.
I have created a shared printer resource that helps those threads to print number. But I am getting confused as how can i make the number to be visible by all threads.
The problem is eachthread is seeing their own copy of number while I need the same number to be shared by all threads.
I am trying to create this example for learning purposes. I have seen other pages on SO that had same kind of problem but I am not able to get the concept.
Any help is appreciated.
how is this example diffrent from what I am doing?
Printing Even and Odd using two Threads in Java
public class PrintAlternateNumber {
public static void main(String args[]) {
SharedPrinter printer = new SharedPrinter();
Thread t1 = new Thread(new myRunnable2(printer,10,1),"1");
Thread t2 = new Thread(new myRunnable2(printer,10,2),"2");
Thread t3 = new Thread(new myRunnable2(printer,10,3),"3");
t1.start();
t2.start();
t3.start();
}
}
class myRunnable2 implements Runnable {
int max;
SharedPrinter printer;
int threadNumber;
int number=1;
myRunnable2(SharedPrinter printer,int max,int threadNumber) {
this.max=max;
this.printer=printer;
this.threadNumber=threadNumber;
}
#Override
public void run() {
System.out.println(" The thread that just entered run "+ Thread.currentThread().getName());
for(int i =1;i<max;i++){
try {
printer.print(i,threadNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SharedPrinter {
boolean canPrintFlag=false;
public synchronized void print(int number,int threadNumber) throws InterruptedException{
if(number%3==threadNumber) {
canPrintFlag=true;
}
while(!canPrintFlag)
{
System.out.println(Thread.currentThread().getName() + " is waiting as it cannot print " + number);
wait();
}
System.out.println(Thread.currentThread().getName()+" printed "+number);
canPrintFlag=false;
notifyAll();
}
}
//output
//The thread that just entered run 2
// The thread that just entered run 3
//The thread that just entered run 1
//3 is waiting as it cannot print 1
//1 printed 1
//1 is waiting as it cannot print 2
//3 is waiting as it cannot print 1
//2 is waiting as it cannot print 1
Technique second
it is still incomplete but I am close
output
0printed by0
2printed by2
1printed by1
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class AlternateNumber {
public static void main(String args[]) {
printerHell ph = new printerHell();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i=0;i<10;i++)
{
queue.add(i);
}
Thread t1 = new Thread(new myRunnableHell(queue,0,ph),"0");
Thread t2 = new Thread(new myRunnableHell(queue,1,ph),"1");
Thread t3 = new Thread(new myRunnableHell(queue,2,ph),"2");
t1.start();
t2.start();
t3.start();
}
}
class myRunnableHell implements Runnable {
BlockingQueue<Integer> queue;
int threadNumber;
printerHell ph;
myRunnableHell(BlockingQueue<Integer> queue, int threadNumber,printerHell ph) {
this.queue=queue;
this.threadNumber=threadNumber;
this.ph=ph;
};
int currentNumber;
#Override
public void run() {
for(int i=0;i<queue.size();i++)
{
currentNumber=queue.remove();
if(threadNumber%3==currentNumber)
{
ph.print(currentNumber);
}
}
}
}
class printerHell {
public synchronized void print(int Number)
{
System.out.println(Number + "printed by" + Thread.currentThread().getName());
}
}
Please see my solution here..
Using simple wait/notify
https://stackoverflow.com/a/31668619/1044396
Using cyclic barriers:
https://stackoverflow.com/a/23752952/1044396
For your query on 'How different it is from even/odd thread problem.
--> it is almost same ... instead of maintaining two states have one more state to call the third thread, so I believe,this can be extended any number of threads.
EDIT:
You may view this approach when you want to have 'n' number of threads to do the work sequentially.(Instead of having different classes t1,t2,t3 etc)
https://codereview.stackexchange.com/a/98305/78940
EDIT2:
Copying the code here again for the above solution
I tried to solve using a single class 'Thrd' which gets initialized with its starting number.
ThreadConfig class which as size of total number of threads you want to create.
State class which maintains the state of the previous thread.(to maintain ordering)
Here you go..(please review and let me know your views)
EDIT:
How it works -->
when a thread Tx gets a chance to execute.. it will set state variable's state with x. So a next thread(Tx+1) waiting , will get a chance once state gets updated. This way you can maintain the ordering of threads.
I hope i am able to explain the code. Please run it and see or let me know for any specific queries on the below code
1)
package com.kalyan.concurrency;
public class ThreadConfig {
public static final int size = 5;
}
2) package com.kalyan.concurrency;
public class State {
private volatile int state ;
public State() {
this.state =3;
}
public State(int state) {
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
3) package com.kalyan.concurrency;
public class Thrd implements Runnable {
int i ;
int name;
int prevThread;
State s;
public Thrd(int i,State s) {
this.i=i;
this.name=i;
this.prevThread=i-1;
if(prevThread == 0) prevThread=ThreadConfig.size;
this.s=s;
}
#Override
public void run() {
while(i<50)
{
synchronized(s)
{
while(s.getState() != prevThread)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==prevThread)
System.out.println("t"+ name+ i);
s.setState(name);
i = i +ThreadConfig.size ;
s.notifyAll();
}
}
}
}
4)
package com.kalyan.concurrency;
public class T1t2t3 {
public static void main(String[] args) {
State s = new State(ThreadConfig.size);
for(int i=1;i<=ThreadConfig.size;i++)
{
Thread T = new Thread(new Thrd(i,s));
T.start();
}
}
}
OUTPUT:
t11
t22
t33
t44
t55
t16
t27
t38
t49
t510
t111
t212
t313
t414
t515
t116..............
I hope I understood you right, but there are to main "features" in java to make a variable being shared between threads:
the volatile keyword
volatile int number = 1;
AtomicInteger (a standard java class -> no library)
AtomicInteger number = new AtomicInteger(1);
These two techniques should both do what you want, however I have no experience using it, I just came upon this word, didn't know what it means and did some digging.
Some stuff to read: ;)
volatile for java explained --> http://java.dzone.com/articles/java-volatile-keyword-0
a better explanation (with IMAGES!!) but for c# (which is still the same usage) --> http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
And a link to some usages of AtomicInteger --> https://stackoverflow.com/a/4818753/4986655
I hope I could help you or at least send you in the right direction :)
- superfuzzy

Java - two threads with wait() and notify()

I am new to Java programming. i want to run two threads using wait() and notify(). But I cant use task flags for thread synchronization,sleep, yield or wait(parameter).I wrote it, but i had to use sleep. can someone help me to change it to without sleep.
This is my main class
public class mainClass{
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
for(int i=0; i<100; i++){
final int z = i;
Thread trainer = new Thread(new Runnable(){
public void run(){
try{
processor.produce(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable(){
public void run(){
try{
processor.consume(z);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
}
System.out.println("100 Tasks are Finished.");
}
}
this is my second class.
public class Processor {
public void produce(int n) throws InterruptedException {
synchronized (this){
System.out.println("Trainer making " + (n+1) + " Task..." );
wait();
System.out.println("");
}
}
public void consume(int m) throws InterruptedException {
Thread.sleep(1);
//I want to run the code without using sleep and get same output
synchronized (this){
System.out.println("Sportman doing " + (m+1) + " Task...");
notify();
}
}
}
this is my output.
Trainer making 1 Task...
Sportman doing 1 Task...
Trainer making 2 Task...
Sportman doing 2 Task...
.
.
.
Trainer making 99 Task...
Sportman doing 99 Task...
Trainer making 100 Task...
Sportman doing 100 Task...
100 Tasks are Finished.
thank you. my english is bad. sorry for it.
Hints:
The correct use of wait involves waiting for something specific to happen. The correct implementation is something like this
synchronize (x) {
while (!x.itHasHappened()) {
x.wait(); // for it to happen
}
}
The loop is necessary since it is possible to get spurious notifies on a primitive lock.
In your specific example, ask yourself what must wait for what to happen. I think you've got it wrong. What is produce(N) actually waiting for, and why?
In mainClass you created 100 times two threads, I think you should create two threads only and in those two threads run the loop 100 times.
Probably you needed to do something like this...
The producer should create together 100 task (one at a time) and wait after each task for the consumer to be done.
The consumer should wait for a task and notify the producer when finished with the current task, them wait for the next task.
So your mainClass should look like this, loops should be in the producer() and consumer() methods.
public class mainClass {
public static void main(String args[]) throws InterruptedException {
final Processor processor = new Processor();
Thread trainer = new Thread(new Runnable() {
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread sportsman = new Thread(new Runnable() {
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
trainer.start();
sportsman.start();
trainer.join();
sportsman.join();
System.out.println("100 Tasks are Finished.");
}
}
And the Processor maybe something like this...
public class Processor {
private int taskNo = 0; // the number of the current task
// (0 = there is no task, but will be)
// (-1 = there won't be more task)
public void produce() throws InterruptedException {
synchronized (this) {
for (int i = 0; i < 100; i++) {
taskNo = i + 1; // making a task number (i+1)
System.out.println("Trainer making " + taskNo + " Task...");
notify(); // notifies the consumer that the task was made
wait(); // and waiting the consumer to finish... zzzz...
System.out.println("");
}
taskNo = -1; // there will be no more task
notify(); // notify the consumer about it
}
}
public void consume() throws InterruptedException {
synchronized (this) {
do {
if (taskNo == 0) {
wait(); // there is no task to do, waiting... zzzz...
}
if (taskNo != -1) {
System.out.println("Sportman doing " + taskNo + " Task...");
taskNo = 0; // sets the task to done
notify(); // notifies the producer that the task was done
}
} while (taskNo != -1);
}
}
}
Typically there is a queue instead of the taskNo variable, where the producer puts tasks and the consumer takes tasks from in. But in your case the queue can have only 1 task at a time, because the producer should wait for the consumer to finish. So you can use a simple variable (taskNo) instead of a queue.

Java Threads - illegal monitor state exception

I am trying to implement threads where one thread generates a random number while another thread waits once it generates random number it should notify and wait for the other thread to do the same. I am getting illegal monitor state exception, please help me out and point out my mistake
class Dice
{
int diceValue;
public Dice()
{
this.diceValue=0;
}
}
public class DiceGame implements Runnable
{
Dice d;
public DiceGame()
{
this.d=new Dice();
}
public void run()
{
if(Thread.currentThread().getName().equals("Player 1"))
{
Random rg=new Random();
for(int i=0;i<6;i++)
{
synchronized(d)
{
d.diceValue=rg.nextInt(6);
System.out.println(Thread.currentThread().getName()+" dice Value is "+d.diceValue);
d.notifyAll();
try
{
d.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
else if(Thread.currentThread().getName().equals("Player 2"))
{
Random rg=new Random();
for(int i=0;i<6;i++)
{
synchronized(d)
{
try
{
d.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
d.diceValue=rg.nextInt(6);
System.out.println(Thread.currentThread().getName()+"dice Value is ");
d.notifyAll();
}
}
}
}
public static void main(String []args)
{
DiceGame dg=new DiceGame();
Thread tr1=new Thread(dg);
Thread tr2=new Thread(dg);
tr1.setName("Player 1");
tr2.setName("Player 2");
tr1.start();
tr2.start();
}
}
synchronized(d)
{
try
{
d.wait();
Any time you see an unconditional call to wait, you know there's a bug right there. Before you wait, you have to make sure the thing you're waiting for didn't already happen. That's the reason you entered synchronized a block, right?
The whole point of the wait/notify mechanism is that you can atomically release a lock and await notification. That can't possibly work if you don't check the predicate (the thing that you're waiting for) before calling wait.
Here synchronized block is necessary to hold the monitor when calling wait.
Right, because unless you're inside a synchronized block, there's no way you can tell whether the thing you're waiting for has already happened or not. And since you must check whether it's already happened before you wait for it, you can only call wait from inside a synchronized block. But you didn't check! You understand the requirement but not its rationale, so you formally met it, but still managed to create the very problem the requirement is designed to prevent!
I guess, the problem is that you are notifying every other thread before waiting youself.
d.notifyAll();
try
{
d.wait();
}
Refer to this post: https://stackoverflow.com/a/828341/5602214
Your code could be improved in several ways, but with a few little hacks it can work:
class Dice
{
int diceValue;
public Dice()
{
this.diceValue=0;
}
}
public class DiceGame implements Runnable
{
Dice d;
public DiceGame()
{
this.d=new Dice();
}
#Override
public void run()
{
if(Thread.currentThread().getName().equals("Player 1"))
{
final Random rg=new Random();
for(int i=0;i<6;i++)
{
synchronized(d)
{
d.diceValue=rg.nextInt(6);
System.out.println(Thread.currentThread().getName()+" dice Value is "+d.diceValue);
d.notifyAll();
try
{
d.wait();
}
catch (final InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
else if(Thread.currentThread().getName().equals("Player 2"))
{
final Random rg=new Random();
for(int i=0;i<6;i++)
{
synchronized(d)
{
try
{
d.wait();
}
catch (final InterruptedException e)
{
e.printStackTrace();
}
d.diceValue=rg.nextInt(6);
System.out.println(Thread.currentThread().getName()+" dice Value is "+d.diceValue);
d.notifyAll();
}
}
}
}
public static void main(final String []args) throws InterruptedException
{
final DiceGame dg=new DiceGame();
final Thread tr1=new Thread(dg);
final Thread tr2=new Thread(dg);
tr1.setName("Player 1");
tr2.setName("Player 2");
tr2.start();
Thread.sleep(100);
tr1.start();
}
}
I got no illegalMonitorstate exception, but the first thread get locked up forever. Basically the problem is that the first thread rolls the dice, and calls d.notifyAll before actually the 2nd thread could start and waiting for the dice. This is naively solved by first starting thread 2 then waiting a bit and start thread 1.
You might also consider:
using the Java convention for braces { }
rg.nextInt gives values between 0..5, not 1..6
it is bad idea to make the thread code work differently depending on the name of the thread. In OOP different behavior is expressed with descendant classes instead.
I guess you're wishing for an universal solution for rolling the dice with multiple players. This problem is not necessarily a problem which requires concurrent programming, since rolling the dice goes serially amongst players. You can of course have the players as Threads, but only one Thread will be active at any point of time. In case of using Threads, you shall implement your own scheduling logic which ensures consistent one-after-another scheduling of threads. Using a monitor (e.g. synchornize(d)) does not offer any guarantee of the ordering, it is only built to guarantee that up to one thread can access to the dice at any point in time.
A solution with any number of players but no threads (this is not a concurrency problem after all) shows this behavior:
import java.util.Random;
class Dice {
private final Random rg=new Random();
private int diceValue=1;
public void roll() {
diceValue=rg.nextInt(6)+1;
}
#Override
public String toString() {
return "value="+diceValue;
}
}
public class Player extends Thread {
Dice dice;
int rollsLeft=6;
public Player(final Dice dice) {
this.dice=dice;
}
#Override
public void run() {
while (rollsLeft>0) {
synchronized(dice) {
// dice obtained
dice.roll();
System.out.println(Thread.currentThread().getName()+" rolled "+dice);
}
// dice released
rollsLeft--;
// just wait a little to make it slower and let other threads to join
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
// ignore
}
}
}
public static void main(final String []args) throws InterruptedException {
final Dice dice=new Dice();
final Player player1=new Player(dice);
final Player player2=new Player(dice);
player1.start();
player2.start();
}
}
Which gives:
Thread-0 rolled value=1
Thread-1 rolled value=6
Thread-0 rolled value=2
Thread-0 rolled value=4
Thread-1 rolled value=2
etc...
As you can see, the order (i.e. player1, player2, player1, player2) is not guaranteed.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class Dice {
private final Random rg=new Random();
private int diceValue=1;
public void roll() {
diceValue=rg.nextInt(6)+1;
}
#Override
public String toString() {
return "value="+diceValue;
}
}
public class Player {
Dice dice;
String player;
public Player(final Dice dice,final String player) {
this.dice=dice;
this.player=player;
}
public void roll() {
dice.roll();
System.out.println(player+" rolled "+dice);
}
public static void main(final String []args) throws InterruptedException {
final Dice dice=new Dice();
final List<Player> players=new ArrayList<Player>();
players.add(new Player(dice,"Ann"));
players.add(new Player(dice,"Ben"));
players.add(new Player(dice,"Cecil"));
players.add(new Player(dice,"Denise"));
for (int rounds=0;rounds<6;rounds++) {
System.out.println("---");
for (final Player player:players) {
player.roll();
}
}
}
}
Which gives you the expected output, i.e. Ann, Ben, Cecil, Denise has 6 rounds of rolling the dice.

A good small example to demonstrate wait() and notify() method in java

Can anybody please provide me a good small example demonstrate wait() and notify() functionality in java. I've tried with the below piece of code but it's not showing what i expected.
public class WaitDemo {
int i = 10;
int display() {
System.out.println("Lexmark");
i++;
return i;
}
}
public class ClassDemo1 extends Thread {
private WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
ClassDemo1 cd1 = new ClassDemo1();
ClassDemo1 cd2 = new ClassDemo1();
cd1.setName("Europe");
cd2.setName("America");
cd1.start();
cd2.start();
}
synchronized void display() {
System.out.println("Hello");
notifyAll();
}
public void run() {
synchronized (this) {
try {
{
notify();
System.out.println("The thread is " + currentThread().getName());
wait();
System.out.println("The value is " + wd.display());
}
} catch (InterruptedException e) {
}
}
}
}
The issue is that the method in the class WaitDemo is not getting executed and as per my idea the SOP after wait() should execute. Please help me out on this.
You've got two levels of braces { in your try block. If you remove the inner set (which doesn't appear to do anything), does that fix the problem?
There are several examples around, all of which demonstrate the use. The last link is a set of results that can help you out. If you need more specific things, let me know what it is that your app is trying to do, and I can try to find examples that are more specific to your situation.
http://www.javamex.com/tutorials/wait_notify_how_to.shtml
http://www.java-samples.com/showtutorial.php?tutorialid=306
http://www.coderanch.com/t/234235/threads/java/Wait-Example
https://www.google.com/search?q=wait%28%29+example+java&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
Below is an example of wait & notify in the Object class. The customer is trying to withdraw money of value 2000 but the account is having only 1000 so it has to wait for the deposit. Once the deposit is made, then the customer will be able to withdraw the amount. Until the deposit is made, the customer will be waiting.
class Cust {
private int totalAmount = 1000;
public synchronized void withdrawal(int amount) {
System.out.println("Total amount " + totalAmount + " withdrawing amount " + amount);
while (this.totalAmount < amount) {
System.out.println("not enough amount..waiting for deposit..");
try { wait(); } catch (Exception e) {}
}
this.totalAmount -= amount;
System.out.println("Withdrawal successful.. Remaining balance is "+totalAmount);
}
public synchronized void deposit(int amount){
System.out.println("Depositing amount "+amount);
this.totalAmount += amount;
System.out.println("deposit completed...and Now totalAmount is " + this.totalAmount);
notify();
}
}
class Depo implements Runnable {
Cust c; int depo;
Depo(Cust c, int depo){
this.c = c;
this.depo = depo;
}
#Override
public void run() {
c.deposit(depo);
}
}
class Withdrawal implements Runnable {
Cust c; int with;
Withdrawal(Cust c, int with){
this.c = c;
this.with = with;
}
#Override
public void run() {
c.withdrawal(with);
}
}
public class ObjectWaitExample {
public static void main(String[] args) {
Cust c = new Cust();
Thread w = new Thread(new Withdrawal(c, 2000));
Thread d1 = new Thread(new Depo(c, 50));
Thread d2 = new Thread(new Depo(c, 150));
Thread d3 = new Thread(new Depo(c, 900));
w.start();
d1.start();
d2.start();
d3.start();
}
}
I created two threads one for printing odd numbers (OddThread) and another for even numbers (EvenThread). Inside the run method of each of the threads I used the shared object of class Print to call printOdd() and printEven() for the Odd and EvenThread respectively. I made the shared object of Print static so that only one copy is made. Now synchronizing on the Print object I used a Boolean flag such that when the odd thread printed an odd number it will be sent into the waiting state and the at the same time notifying the even thread to execute. The logic is written in such a way that the odd thread will always print the odd number first no matter what, as the flag is set to false initially preventing the even thread to execute and sending it to a waiting state.
package com.amardeep.test;
public class ThreadDemo {
// Shared object
static Print print = new Print();
public static void main(String[] args) {
new Thread(new OddThread()).start();
new Thread(new EvenThread()).start();
}
}
class EvenThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printEven();
}
}
class OddThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printOdd();
}
}
class Print {
public volatile boolean flag = false;
public synchronized void printEven() {
for (int i = 1; i <= 10; i++) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 == 0) {
System.out.println("from even " + i);
flag = false;
notifyAll();
}
}
}
}
public synchronized void printOdd() {
for (int i = 1; i <= 10; i++) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 != 0) {
System.out.println("from odd " + i);
flag = true;
notifyAll();
}
}
}
}
}
output:-
from odd 1
from even 2
from odd 3
from even 4
from odd 5
from even 6
from odd 7
from even 8
from odd 9
from even 10
Your problem is that you are creating two instances of the Thread class. Thus when the wait() is called, it is on two different instances, neither of which has another thread that is in contention for your monitor, nor is there another thread to call notifyAll() to wake the thread from its wait state.
Thus each thread you have started will wait forever (or until interrupted for some other reason).
You want to have multiple threads accessing the same monitor, so start by trying to code something in which the code in question is not actually a thread, but is simply being used by a thread.
#normalocity has already provided links to multiple examples.
I just updated this answer to include an SCCE.
The workers call pauseIfNeeded on the WorkerPauseManager. If the manager is paused when the worker thread calls pauseIfNeeded(), we call wait(), which tells the calling thread to wait until a different thread calls notify() or notifyAll() on the object being waited on. This happens when the Swing Event Dispatch Thread calls play() on the manager, which in turn calls notifyAll().
Note that you must have a synchronized lock on the object you are calling wait() or notify() on. Since the methods in WorkerPauseManager are synchronized, all the synchronized methods are getting a synchronized lock on the WorkerPauseManager itself.
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* #author sbarnum
*/
public class WorkerPauseManagerTest {
public static void main(String[] args) {
final WorkerPauseManager pauseManager = new WorkerPauseManager();
new Worker("Worker 1", pauseManager).start();
new Worker("Worker 2", pauseManager).start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") {
public void actionPerformed(final ActionEvent e) {
JToggleButton source = (JToggleButton) e.getSource();
if (source.isSelected()) {
pauseManager.start();
source.setText("Pause");
} else {
pauseManager.pause();
source.setText("Play");
}
}
});
playPauseButton.setSelected(true); // already running
JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
});
}
private static class Worker extends Thread {
final String name;
final WorkerPauseManager pauseManager;
public Worker(final String name, final WorkerPauseManager pauseManager) {
this.name = name;
this.pauseManager = pauseManager;
}
#Override
public void run() {
while (!Thread.interrupted()) {
try {
pauseManager.pauseIfNeeded();
System.out.println(name + " is running");
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static final class WorkerPauseManager {
private boolean paused;
public synchronized void pauseIfNeeded() throws InterruptedException {
if (paused) wait();
}
public synchronized void pause() {
this.paused = true;
}
public synchronized void start() {
this.paused = false;
notifyAll();
}
}
}
What wait method does is , when some thread executed a synchronized block by locking some object (we call that object is "a") , then inside that synchronized block when the thread executed the wait method of object "a" like this
A a = new A (); // some class object call "a"
synchronized (a){
a.wait ();//exceptions must be handled
}
Then the a object will release and the thread has to go to the wait state until it has been release from that state.
and anothet thread now can use the a object beacause its a release object. so if another thread locked that object and it executed the notify method from that object like
a.notify ()
Then one of a thread of the threads that went to wait state by object "a" can be released from the wait state. Other wise when call the notifyAll then the all the thread objects will release from that state.
/*
* the below program is like
* tread t1 will first run , and it comes to "notify()" method
* there are no threds waiting bcoz this is the first thread.
* so it will not invoke any other threads. next step is "wait()" method
*will be called and the thread t1 in waiting state. next stament
* "System.out.println("The value is ..."+wd.display());" will not be executed
* because thread t1 is in waiting state.
*
* thread t2 will run ,and it comes to "notify()" method ,there is already
* thread t1 is in waiting state ,then it will be invoked.now thread t1 will
* continue execution and it prints the statement "System.out.println("The value is ..."+wd.display())"
* and thread t2 will be in waiting state now.
*
* if you uncomment "notifyAll()" method then, after t1 thread completes its execution
*then immediately "notifyAll()" method will be called,by that time thread t2 is
* already in waiting state , then thread t2 will be invoked and continues execution.
*or
* if any other threadds are in waiting state all those threads will be invoked.
*/
package threadsex;
/**
*
* #author MaheshM
*/
/**
* #param args the command line arguments
*/
public class WaitNotifyNotifyAllDemo implements Runnable {
WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
WaitNotifyNotifyAllDemo cd1 = new WaitNotifyNotifyAllDemo();
Thread t1 = new Thread(cd1);
t1.setName("mahi1");
Thread t2 = new Thread(cd1);
t2.setName("mahi2");
t1.start();
t2.start();
}
#Override
public void run() {
synchronized (this) {
try {
System.out.println("The thread is=" +
Thread.currentThread().getName());
notify();
wait();
System.out.println("The value is ..." + wd.display());
// notifyAll();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}

Java: Threads, how to make them all do something

I am trying to implement nodes talking to each other in Java. I am doing this by creating a new thread for every node that wants to talk to the server.
When the given number of nodes, i.e. that many threads have been created, have connected to the server I want each thread to execute their next bit of code after adding to the "sharedCounter".
I think I need to use 'locks' on the shared variable, and something like signalAll() or notifyAll() to get all the threads going, but I can't seem to make clear sense of exactly how this works or to implement it.
Any help explaining these Java concepts would be greatly appreciated :D
Below is roughly the structure of my code:
import java.net.*;
import java.io.*;
public class Node {
public static void main(String[] args) {
...
// Chooses server or client launchers depend on parameters.
...
}
}
class sharedResource {
private int sharedCounter;
public sharedResource(int i) {
sharedCounter = i;
}
public synchronized void incSharedCounter() {
sharedCounter--;
if (sharedCounter == 0)
// Get all threads to do something
}
}
class Server {
...
for (int i = 0; i < numberOfThreads; i++) {
new serverThread(serverSocket.accept()).start();
}
...
sharedResource threadCount = new sharedResource(numberOfThreads);
...
}
class serverThread extends Thread {
...
//some code
Server.threadCount.incSharedCounter();
// Some more code to run when sharedCounte == 0
...
}
class Client {
...
}
     // Get all threads to do something
Threads (or rather Runnables, which you should implement rather than extending Thread) have a run method that contains the code they are expected to execute.
Once you call Thread#start (which in turn calls Runnable#run), the thread will start doing exactly that.
Since you seem to be new to multi-threading in Java, I recommend that you read an introduction to the Concurrency Utility package, that has been introduced in Java5 to make it easier to implement concurrent operations.
Specifically what you seem to be looking for is a way to "pause" the operation until a condition is met (in your case a counter having reached zero). For this, you should look at a CountDownLatch.
Indeed, the subject is broad, but I'll try to explain the basics. More details can be read from various blogs and articles. One of which is the Java trail.
It is best to see each thread as being runners (physical persons) that run alongside each other in a race. Each runner may perform any task while running. For example, take a cup of water from a table at a given moment in the race. Physically, they cannot both drink from the same cup at once, but in the virtual world, it is possible (this is where the line is drawn).
For example, take again two runners; each of them has to run back and forth a track, and push a button (shared by the runners) at each end for 1'000'000 times, the button is simply incrementing a counter by one each time. When they completed their run, what would be the value of the counter? In the physical world, it would be 2'000'000 because the runners cannot push the button at the same time, they would wait for the first one to leave first... that is unless they fight over it... Well, this is exactly what two threads would do. Consider this code :
public class ThreadTest extends Thread {
static public final int TOTAL_INC = 1000000;
static public int counter = 0;
#Override
public void run() {
for (int i=0; i<TOTAL_INC; i++) {
counter++;
}
System.out.println("Thread stopped incrementing counter " + TOTAL_INC + " times");
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new ThreadTest();
Thread t2 = new ThreadTest();
t1.start();
t2.start();
t1.join(); // wait for each thread to stop on their own...
t2.join(); //
System.out.println("Final counter is : " + counter + " which should be equal to " + TOTAL_INC * 2);
}
}
An output could be something like
Thread stopped incrementing counter 1000000 times
Thread stopped incrementing counter 1000000 times
Final counter is : 1143470 which should be equal to 2000000
Once in a while, the two thread would just increment the same value twice; this is called a race condition.
Synchronizing the run method will not work, and you'd have to use some locking mechanism to prevent this from happening. Consider the following changes in the run method :
static private Object lock = new Object();
#Override
public void run() {
for (int i=0; i<TOTAL_INC; i++) {
synchronized(lock) {
counter++;
}
}
System.out.println("Thread stopped incrementing counter " + TOTAL_INC + " times");
}
Now the expected output is
...
Final counter is : 2000000 which should be equal to 2000000
We have synchronized our counter with a shared object. This is like putting a queue line before only one runner can access the button at once.
NOTE : this locking mechanism is called a mutex. If a resource can be accessed by n threads at once, you might consider using a semaphore.
Multithreading is also associated with deadlocking. A deadlock is when two threads mutually waits for the other to free some synchronized resource to continue. For example :
Thread 1 starts
Thread 2 starts
Thread 1 acquire synchronized object1
Thread 2 acquire synchronized object2
Thread 2 needs to acquire object2 for continuing (locked by Thread 1)
Thread 1 needs to acquire object1 for continuing (locked by Thread 2)
Program hangs in deadlock
While there are many ways to prevent this from happening (it depends on what your threads are doing, and how they are implemented...) You should read about that particularly.
NOTE : the methods wait, notify and notifyAll can only be called when an object is synchronized. For example :
static public final int TOTAL_INC = 10;
static private int counter = 0;
static private Object lock = new Object();
static class Thread1 extends Thread {
#Override
public void run() {
synchronized (lock) {
for (int i=0; i<TOTAL_INC; i++) {
try {
lock.wait();
counter++;
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
static class Thread2 extends Thread {
#Override
public void run() {
synchronized (lock) {
for (int i=0; i<TOTAL_INC; i++) {
try {
lock.notify();
counter--;
lock.wait();
} catch (InterruptedException e) {
/* ignored */
}
}
}
}
}
Notice that both threads are running their for...loop blocks within the synchronized block. (The result of counter == 0 when both threads end.) This can be achieved because they "let each other" access the synchronized resource via the resource's wait and notify methods. Without using those two methods, both threads would simply run sequentially and not concurrently (or more precisely, alternately).
I hope this shed some light about threads (in Java).
** UPDATE **
Here is a little proof of concept of everything discussed above, using the CountDownLatch class suggested by Thilo earlier :
static class Server {
static public final int NODE_COUNT = 5;
private List<RunnableNode> nodes;
private CountDownLatch startSignal;
private Object lock = new Object();
public Server() {
nodes = Collections.synchronizedList(new ArrayList<RunnableNode>());
startSignal = new CountDownLatch(Server.NODE_COUNT);
}
public Object getLock() {
return lock;
}
public synchronized void connect(RunnableNode node) {
if (startSignal.getCount() > 0) {
startSignal.countDown();
nodes.add(node);
System.out.println("Received connection from node " + node.getId() + " (" + startSignal.getCount() + " remaining...)");
} else {
System.out.println("Client overflow! Refusing connection from node " + node.getId());
throw new IllegalStateException("Too many nodes connected");
}
}
public void shutdown() {
for (RunnableNode node : nodes) {
node.shutdown();
}
}
public void awaitAllConnections() {
try {
startSignal.await();
synchronized (lock) {
lock.notifyAll(); // awake all nodes
}
} catch (InterruptedException e) {
/* ignore */
shutdown(); // properly close any connected node now
}
}
}
static class RunnableNode implements Runnable {
private Server server;
private int id;
private boolean working;
public RunnableNode(int id, Server server) {
this.id = id;
this.server = server;
this.working = true;
}
public int getId() {
return id;
}
public void run() {
try {
Thread.sleep((long) (Math.random() * 5) * 1000); // just wait randomly from 0 to 5 seconds....
synchronized (server.getLock()) {
server.connect(this);
server.getLock().wait();
}
if (!Thread.currentThread().isAlive()) {
throw new InterruptedException();
} else {
System.out.println("Node " + id + " started successfully!");
while (working) {
Thread.yield();
}
}
} catch (InterruptedException e1) {
System.out.print("Ooop! ...");
} catch (IllegalStateException e2) {
System.out.print("Awwww! Too late! ...");
}
System.out.println("Node " + id + " is shutting down");
}
public void shutdown() {
working = false; // shutdown node here...
}
}
static public void main(String...args) throws InterruptedException {
Server server = new Server();
for (int i=0; i<Server.NODE_COUNT + 4; i++) { // create 4 more nodes than needed...
new Thread(new RunnableNode(i, server)).start();
}
server.awaitAllConnections();
System.out.println("All connection received! Server started!");
Thread.sleep(6000);
server.shutdown();
}
This is a broad topic. You might try reading through the official guides for concurrency (i.e. threading, more or less) in Java. This isn't something with cut-and-dried solutions; you have to design something.

Categories