Synchronizing threads - java

So I have a code:
public void runThreads(int number)
{
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < number; i++)
{
Thread t = new MyThread(getRandomPerson(),i);
threadList.add(t);
}
for (Thread x : threadList)
{
x.start();
}
}
So I am adding threads to my list of threads and then starting this threads.
This is MyThread class:
public class MyThread extends Thread
{
Person person;
int number;
public MyThread(Person person, int number)
{
this.person = person;
this.number = number;
}
#Override
public void run()
{
try
{
synchronized (this)
{
Thread.sleep(1000);
System.out.println(number + "\t" + person.getSurname());
Thread.sleep(1000);
System.out.println(number + "\t" + person.toString());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
I wanted to make a program which creates the threads, adds them to the list, invokes them but each thread should wait until the previous ended its task.
So output should be like :
1 Surname
/** Waitning second */
1 person.toString()
/** Waiting second*/
And then the second thread start invoking:
2 Surname
....
How to achieve this using synchronized? I tried different ways to use synchronized but it failed.

public class MyThread extends Thread
{
private static Object lock = new Object();
...
synchronized (lock)
{
Thread.sleep(1000);
System.out.println(number + "\t" + person.getSurname());
Thread.sleep(1000);
System.out.println(number + "\t" + person.toString());
}
...
That way you will get the same person's surname and toString() in order. You won't enforce strict ordering on the people, person 7 may still go before person 1.

You need a common lock - at the moment you are synchronizing on this, which is different for each thread. Try something like:
private static final Object lock = new Object();
and synchronize on that static (therefore shared) variable instead.

If you must use threads and if you must have order of execution, then you can do a t.join() immediately after t.start() - this will ensure the following flow:
- Main Thread
- loop
- start child thread
- wait for child thread to finish
- continue loop
- Exit Main thread
But, as pointed before, you don't need threads to do this since you can see that there is absolutely no gain from this approach (apart from academical) and it's detrimental in fact.
And special thanks to #assylias.

Related

Problem with critical section using Retrant Lock with Condition

I have a small project to synchronize multiple (two classes: ships, cars with a few instances with shared bufor class called Harbour) threads at the same time. They will be performing certain action on it. But I can't start with that until I synchronized the threads named "cars" in the Harbour. The Harbour has limited capacity and if this capacity is reached the "car" threads should be waiting until they will get signal that there's a free space to enter. I've used Retrant Lock with Condition but it doesn't work as I think.
public class Harbour {
final Lock protectNr;
final Condition protectNrCon;
int capacity;
int nrOfCars;
public Harbour(int capacity) {
this.capacity = capacity;
this.protectNr = new ReentrantLock();
this.protectNrCon = protectNr.newCondition();
}
public void carEnterHarbour(String name) {
try {
protectNr.lock();
if (this.nrOfCars == this.capacity)
protectNrCon.await();
nrOfCars++;
System.out.println(name + " enters");
System.out.println("Number of cars:" + this.nrOfCars);
protectNr.unlock();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
public void carLeavingHarbour(String name) {
try {
protectNr.lock();
this.nrOfCars--;
protectNrCon.signal();
System.out.println(name + " leaving");
System.out.println("Number of cars:" + this.nrOfCars);
} finally {
protectNr.unlock();
}
}
}
public class Car extends Thread {
Harbour harbour;
public Car(Harbour harbour, String name) {
super(name);
this.harbour = harbour;
}
public void run() {
for (int i = 0; i < 10; i++) {
harbour.carEnterHarbour(getName());
harbour.carLeavingHarbour(getName());
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
int harbourCapacity = 20;
final Harbour harbour = new Harbour(harbourCapacity);
int nrOfCars = 500;
Car[] cars = new Car[nrOfCars];
for (int i = 0; i < nrOfCars; i++)
cars[i] = new Car(harbour, "Car-" + i);
for (int i = 0; i < nrOfCars; i++)
cars[i].start();
for (int i = 0; i < nrOfCars; i++)
cars[i].join();
}
}
What I was expecting after executing this code:
Car-386 leaving
Number of cars:**19**
Car-300 enters
Number of cars:**20**
Car-300 leaving
Number of cars:**19**
What I got:
Car-386 leaving
Number of cars:**20**
Car-300 enters
Number of cars:**21**
Car-295 enters
Number of cars:**22**
I also try to change int capacity to volatile int capacity and add some busy waiting but didn't work at all.
It looks like Threads are not block on Condition and I wonder why is this happening?
The documentation for Condition warns that spurious wakeups might occur (emphasis mine):
When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics. This has little practical impact on most application programs as a Condition should always be waited upon in a loop, testing the state predicate that is being waited for. An implementation is free to remove the possibility of spurious wakeups but it is recommended that applications programmers always assume that they can occur and so always wait in a loop.
Your code doesn't honor that warning.
Your carEnterHarbour() must take this possibility of spurious wakeups into account and needs
while(this.nrOfCars == this.capacity){
protectNrCon.await();
}
instead of the simple if statement.
Depending on your requirements it might be easier to use a Semaphore:
public class Harbour {
final Semaphore slots;
public Harbour(int capacity){
this.slots = new Semaphore(capacity);
}
public void carEnterHarbour(String name) {
try{
slots.acquire();
}catch (InterruptedException e){
System.out.println("Error");
}
}
public void carLeavingHarbour(String name) {
slots.release();
}
}
Note that when using a Semaphore you don't have those locks in place when entering / leaving the Harbour and therefore it is difficult to get that ordered "car entering" / "car leaving" output together with the number of currently available slots.
In the carEnterHarbour method, you are calling await() on the protectNrCon condition, which causes the current thread to wait until it is signaled. However, you are not calling signal() anywhere in the carEnterHarbour method. This means that once a thread enters the if block, it will always wait indefinitely on the condition.
You should consider calling signal() on the protectNrCon condition after you increment nrOfCars and print the message, so that other threads waiting on the condition can be unblocked.
Additionally, you should call await() in a loop to ensure that the thread waits until the condition is true, rather than waiting indefinitely. Here is an example of how you can modify the carEnterHarbour method:
public void carEnterHarbour(String name) {
try {
protectNr.lock();
while (this.nrOfCars == this.capacity) {
protectNrCon.await();
}
nrOfCars++;
System.out.println(name+" enters");
System.out.println("Number of cars:" + this.nrOfCars);
protectNrCon.signal();
} catch (InterruptedException e) {
System.out.println("Error");
} finally {
protectNr.unlock();
}
}

Something wrong with the Peterson algorithm logic?

I am pretty new to Multithreading programming. In my code threads are trying to acquire locks around few lines. The lines work pretty fine for few context switches but then it halts (probably a deadlock).
On the other hand if use synchronized block then all works fine.
I've four classes.
1. PetersonAlgorithm.java
package com.ashish.master;
public class PetersonAlgorithm {
boolean wantCS[] = {false, false};
int turn = 1;
public void requestCS(int i) {
System.out.println("Lock requested by the thread - " + i);
wantCS[i] = true;
turn = 1 - i;
while(wantCS[1-i] && turn == 1-i);
}
public void releaseCS (int i) {
wantCS[i] = false;
turn = i - 1;
System.out.println("Lock released by the thread - " + i);
}
}
If anyone feels that above algorithm is incorrect then let me know, and feel free to make suggestions.
2. Runner.java
package com.ashish.master;
public class Runner {
public static Incrementer runnableInstance = new Incrementer();
public static Thread inc1 = new Thread(runnableInstance, "0");
public static Thread inc2 = new Thread(runnableInstance, "1");
public static void main(String args[]) {
inc1.start();
inc2.start();
try{
inc1.join();
inc2.join();
} catch (InterruptedException ex) {
System.out.println("The threads have been interrupted while waiting for the join ---> " + ex.getMessage());
}
System.out.println("The total turns taken by incrementer are ----> " + runnableInstance.turns);
}
}
3. Incrementer.java - If synchronized block is used instead of the Peterson algorithm, everything works fine.
package com.ashish.master;
public class Incrementer implements Runnable {
public long turns = 0;
public PetersonAlgorithm pa = new PetersonAlgorithm();
#Override
public void run() {
System.out.println("Thread " + this.toString() + "started.....");
while(true) {
pa.requestCS(Integer.parseInt(this.toString()));
// synchronized(this) {
if(DataStore.data < 1000000) printCriticalSection();
else break;
// }
pa.releaseCS(Integer.parseInt(this.toString()));
}
}
public void printCriticalSection() {
System.out.println("The value of the number is increased by thread " +
this.toString() +" to --> " + DataStore.increase());
turns ++;
}
#Override
public String toString() {
return Thread.currentThread().getName();
}
}
4. DataStore.java A class to mock the data source -- simply increase the number
package com.ashish.master;
public class DataStore {
public static long data = 0L;
public static long increase() {
DataStore.data += 1;
return DataStore.data;
}
}
Your runnables never observe each other's monitors (wantCS and turn) as they have different instances... Each runnable needs to work with a same shared set of monitors!
Take the blue pill and make your PetersonAlgorithm variables static volatile with synchronized block access...
Or take the red pill and you create a Class for your flag monitors (wantCS) and for your indicator monitor (turn). Then just define your runnable with one "own flag", one "observed flag" and one "indicator". Both Runnables will have the same indicator instance (therefore needs to be synchronized) while the flag instances will be crossed (the own flag of R1 will be the observed flag of R2 and the own flag of R2 the observed flag of R1). You should synchronized the flag methods too as you don't want to have a flag raised or lowered while being observed.
Then few steps:
Runnables raise their Flag
Runnables turn the shared Indicator ( set to opponent runnable's id )
Wait if opponent's flag is raised and Indicator is set to opponent.
The non waiting opponent does its stuff then lowers its flag.
The waiting opponent stops waiting (opponent's flag has been lowered), does its stuff and lowers its flag.
Each of your runnable instances has its own PetersonAlgorithm instance. Thus, the two runnables don't know anything about each other and will both always get immediate access to the critical section. Try implementing your PetersonAlgorithm class as static class with static methods. Then change the lines
pa.requestCS(Integer.parseInt(this.toString()));
// ...
pa.releaseCS(Integer.parseInt(this.toString()));
into
PetersonAlgorithm.requestCS(Integer.parseInt(this.toString()));
// ...
PetersonAlgorithm.releaseCS(Integer.parseInt(this.toString()));

Why ReentrantLock does not show its unfairness in this demo code?

I was trying to write a code that shows the unfairness of ReentrantLock (when ctor is passed fair=false). To my surprise, ReentrantLock was perfectly fair.
My test has the following logic: spawn 20 threads who have an "id" going from 0 to 19. All threads share a ReentrantLock. Then, in chronological order:
Thread 0 locks the lock.
Thread 1 to 19 block on lock(), in order 1, then 2, then 3, .. , then 19
Thread 0 unlocks the lock. This is the first test of fairness, if the lock is fair, thread 1 should get it thereafter
When thread 1 has the lock, he releases it too. Second test of fairness: thread 2 should now get it.
etc
I was expecting that sometimes, a thread gets the lock before another one that was actually waiting for longer. But it never happens
The code:
package jma.test;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;
class ThreadTest extends Thread {
private final int id;
private final int totalNbThreads;
private final ReentrantLock lock1;
private final LinkedList<Integer> checkOrder;
ThreadTest(int id, int totalNbThreads, ReentrantLock lock, LinkedList<Integer> checkOrder) {
this.id = id;
this.totalNbThreads = totalNbThreads;
this.lock1 = lock;
this.checkOrder = checkOrder;
}
public void run() {
try {
// This if is to force threads to get to lock() call below in order of their ids.
// Thread 0 should call lock() first, then threads 1, 2, 3, 4 ...
if (this.id == 1) {
while (!lock1.isLocked()) {
// wait for thread 0 to lock it
}
} else if (this.id > 1) {
while (lock1.getQueueLength() != (this.id - 1)) {
// íf we are thread n, we wait for thread 1 to n-1 to enter the wait queue.
}
}
lock1.lock();
if (this.id == 0) {
while (lock1.getQueueLength() != (totalNbThreads - 1)) {
// Wait for all other threads to bloc on lock1.lock() before releasing lock
}
}
checkOrder.add(this.id);
} finally {
lock1.unlock();
}
}
}
public class Main {
private static final int NB_THREADS = 20; // at least 2
// change the boolean to switch between fair or not-fair lock
private static final ReentrantLock lock = new ReentrantLock(false);
private static boolean isLockFair() {
Queue<Thread> allThreads = new LinkedList<>();
LinkedList<Integer> checkOrder = new LinkedList<>();
for (int id=0; id < NB_THREADS; id++) {
allThreads.add(new ThreadTest(id, NB_THREADS, lock, checkOrder));
}
for (Thread t : allThreads) {
t.start();
}
for (Thread t : allThreads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int previous = -1;
for (int i : checkOrder) {
if (i != previous + 1) {
System.out.println("not fair: " + i + " got the lock after " + previous);
return false;
}
previous = i;
}
return true;
}
public static void main(String[] args) {
int ctrUnfair = 0;
int nbTest = 10000;
for (int i=0; i<nbTest; i++) {
if (!isLockFair())
ctrUnfair++;
}
System.out.println("unfairness: " + ctrUnfair + "/" + nbTest);
}
}
I assume that, because the thread releasing the lock does not try to get it again, when unlock is called there is no concurrency between the running thread and the blocked threads, so the thread that will get the lock necessarily comes from the wait queue, and the implementation of the wait queue is probably a FIFO. Is it the explanation ?
I was expecting that sometimes, a thread gets the lock before another one that was actually waiting for longer. But it never happens
In my understanding,this happens in the case below.
1.Thread a call unlock,after execute tryRelease but before unparkSuccessor,thread scheduling happens,Thread b start to execute.
2.Thread b call lock,if it is a none fair lock,it will call compareAndSetState and will success,you see though other threads waiting for the lock,but thread b got it,but if it is a fair lock,it will test if current thread is the first thread waiting for the lock ,see hasQueuedPredecessors.
All these comes from the source code AQS and ReentrantLock.
Back to your code,before thread 0 can unlock,all other threads are in the waiting queue,so different with the case above.Hope this helps and if I am wrong,please let me know.

Creating three threads in Java to compute three different items

I'm trying to write my solution to a problem of multithreading in Java:
Create three separate threads that will calculate the average, minimum
and maximum of a series of numbers that is passed to the program. The
values will be stored globally in the program. The three threads will
return the three values respectively to the main program where it will
be output to the user.
I'm new to Java, so I've got one basic question about the approach to this program: How do I create three separate threads that will perform three different functions? While reading multithreading, I've come across several examples wherein three(or more) threads were created which would each execute a single function: counting down a loop. Thus requires only a single call to public void run() and one can very easily create three instances of a class that implements Runnable to do this, something like:
// Create multiple threads.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One"); // start threads
new NewThread("Two");
new NewThread("Three");
try {
// wait for other threads to end
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
I am not sure how to create threads that perform separate functions: calculate double, min and max. So far, I've created one thread that calculates the average and returns it to the main program. This is my code [till now]:
package assignment2;
class Q2Thread implements Runnable {
String name;
Thread t;
private int average;
int sum=0;
Q2Thread(String name)
{
this.name=name;
t=new Thread(this, name);
//System.out.println("This thr");
t.start();
}
public void run()
{
try
{
for(int i=0;i<Q7Main.arr.length;i++)
sum+=Q7Main.arr[i];
average=sum/Q7Main.arr.length;
}
//catch(InterruptedException e)
finally
{
System.out.println("Calcuated average.");
}
System.out.println("Child Thread exiting.");
}
public int getAverage()
{
return average;
}
}
package assignment2;
import java.util.*;
public class Q7Main {
public static int[] arr=new int[5];
static Scanner in=new Scanner(System.in);
private static int finalAverage;
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Please enter the numbers: " );
for(int i=0;i<arr.length; i++)
arr[i]=in.nextInt();
System.out.println("You entered the numbers: ");
for(int x: arr)
{
System.out.print(x+ " ");
}
System.out.println();
Q2Thread obj=new Q2Thread("Average");
try
{
obj.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
finalAverage=obj.getAverage();
System.out.println("The average of the numbers is: "+ finalAverage);
}
}
I have two questions now:
Can someone give me the approach to creating two more threads that will compute the min and max?
Are there any OOP defects in my code(thus far) that I should be aware of?
What you can do is create two other classes that calculate min and max, create an object of each of them obj1 and obj2. Since the constructor starts the thread for you, you should now have 3 threads running asynchronously.
Call obj1.t.join() and obj2.t.join() within that try block. So it should look like this:
try{
obj.t.join();
obj1.t.join();
obj2.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
int average = obj.getAverage();
int max = obj1.getMax();
int min = obj2.getMin();
And then do whatever you want with these numbers.
As for some general comments, firstly I would not have a thread object as an attribute within the runnable class, nor have the start() method within the constructor. Instead, within the main class, I would encourage you to create three thread objects with an instance of each runnable class, and then invoke the start() method on each of them. Furthermore, instead of the three runnable
classes all interacting with the same static array found in Q7Main, I would instead update their
constructors to accept the array as a parameter in the constructor, and then have each of them interact with a unique array object when their run method is invoked. Otherwise, you have an issue that when one thread changes the value of something in the array, you get unexpected results.
Of course in this case none of your classes do that, but its something to keep in mind.
For example
Q2Thread obj =new Q2Thread("Average", arr);
Q2MaxThread obj1 = new Q2MaxThread("Maximum", arr);
Q2MinThread obj2 = new Q2MinThread("Minimum", arr);
Thread avThread = new Thread(obj);
Thread maxThread = new Thread(obj1);
Thread minThread= new Thread(obj2);
avThread.start();
maxThread.start();
minThread.start();
try{
avThread.join();
maxThread.join();
minThread.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
int average = obj.getAverage();
int max = obj1.getMax();
int min = obj2.getMin();
Further to the #ElvenAshwin answer you should probably take three classes as private inner class.... good practice as you build bigger things you dont pollute public api. As an alternate and good exercise, think about doing it with lambdas in java 8. Its just a function you need not the class.

Java Shutdown Hook Issues

My shutdown hooks will not run. The shutdown hook is intended to print out statistics after the program has terminated for all philosopher threads that had been running. The philosopher class extends Thread, and simply chews and eats based on if forks are available or not. Here is my code.
public class Main {
private static ArrayList<Philosopher> philosophers = new ArrayList<Philosopher>();
public static void main(String[] args) {
int counter = 0;
int num = Integer.parseInt(args[0]); // number of philosopher threads to create
for(int x = 0; x < num; x++)
{
Fork one = new Fork(counter);
counter++;
Fork two = new Fork(counter);
counter++;
Philosopher p = new Philosopher(String.valueOf(x), one, two); // (Identifier, fork one, fork two)
philosophers.add(p);
}
// Create shutdown hook
Stats s = new Stats(philosophers);
Runtime.getRuntime().addShutdownHook(s);
// Start all philosopher threads
for(Philosopher phil : philosophers)
{
phil.start();
}
}
}
public class Stats extends Thread{
private ArrayList<Philosopher> list = new ArrayList<Philosopher>();
public Stats(ArrayList<Philosopher> al)
{
list = al;
}
public void run()
{
System.out.println("Test");
for(Philosopher p : list)
{
System.out.println(p.getPhilName() + " thought for " + p.getTimeThinking() + " milliseconds and chewed for " + p.getTimeChewing() + " milliseconds.");
}
}
}
Thanks for any help you can provide, I greatly appreciate it.
You're creating Philosopher instances but are not adding them to list, hence the list remains empty and your shut-down hook appears not to run because it won't print anything to stdout.
EDIT
Following your recent comment the next thing I'd suggest is to add logging to prove that all threads are terminating. For example, you could join with each philosopher thread from your main thread so that when your main thread terminates you are certain that each philosopher thread has previously terminated.
// Start all philosopher threads
for (Philosopher phil : philosophers) {
phil.start();
}
for (Philosopher phil : philosophers) {
System.err.println("Joining with thread: " + phil.getName());
phil.join();
}
System.err.println("Main thread terminating.");
// Shut-down hook should now run.
}

Categories