Understanding thread synchronization using semaphores - java

I'm trying to understand semaphores. If I want to print out something like #//}}} repeatedly (with \n after each character), how could I do that with semaphores printing only 1 visible character at a time? I have an idea on how to print out one character each using similar code for each semaphore:
public static class PrintB implements Runnable // similar class for each semaphore
{
public void run(){
for (int i=0; i<count; i++) { // printing lots to see functionality
try {
printableB.acquire(); // the semaphore
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf( "%s\n", "/"); // Need 2 /'s
printableC.release(); // handled B's print, move to C
}
}
}
The problem here is that the rest of my code will only print "#/}" and not "#//}}}". I don't want to just put in other print statements to accomplish this. I want to only use semaphore-related statements like .acquire() and .release() (I'm trying to learn about them after all!). Any ideas? Thank you!

Related

Threading in Java (practicing for college)

Create a program that simulates training at an athletic stadium,
there is one track in the stadium that can be used by up to 5 people at a time
and the coach does not allow that number to exceed, but when some of the athletes finish their run (2sec)
and free up space then notify other athlete for running.
After 2 seconds, all processes are frozen
My question is, could anyone explain to me why something like this does not work and how to handle this problem?
class JoggingTrack {
public int numOfAthlete;
public JoggingTrack() {
this.numOfAthlete = 0;
}
#Override
public String toString() {
return "\nNumber of Athlete: " + numOfAthlete + "\n";
}
}
class Athlete extends Thread {
private JoggingTrack track;
private boolean running;
public Athlete(JoggingTrack s) {
this.track = s;
this.running = false;
}
public synchronized boolean thereIsSpace() {
if(track.numOfAthlete < 5) {
return true;
}
return false;
}
public synchronized void addAthlete() {
track.numOfAthlete++;
this.running = true;
}
public synchronized void removeAthlete() {
track.numOfAthlete--;
this.running = false;
}
#Override
public void run() {
try {
while(true) {
while(!this.thereIsSpace()) {
wait();
}
while(!this.running) {
addAthlete();
sleep(2000);
}
while(this.running) {
removeAthlete();
notify();
}
}
} catch (Exception e) {
}
}
}
public class Program {
static JoggingTrack track;
static Athlete[] a;
public static void main(String[] args) {
track = new JoggingTrack();
a = new Athlete[10];
for(int i = 0; i < 10; i++) {
a[i] = new Athlete(track);
a[i].start();
}
while(true) {
try {
System.out.println(track);
Thread.sleep(500);
} catch (Exception e) {
}
}
}
}
A lot of issues with this.
Your methods are in the wrong place. The synchronized keyword synchronizes on an instance of the class, not across multiple instances. So your remove and add functions on different athletes would cause race conditions. These functions should be moved to the Track object, because all athletes are using the same track (so should your isThereSpace function). At the same time, you should not be directly accessing the member variables of Track in Athlete, use a getter for it instead.
Secondly, you use of wait and notify are wrong. They leave lots of holes for race conditions, although it may work most of the time. And this isn't really a good place for using them- a counting semaphore in the Track class would be a better solution- its exactly what counting semaphores are made for. Look at the Semaphore class for more details. Its basically a lock that will allow N owners of the lock at a time, and block additional requesters until an owner releases it.
Your threads are waiting forever, because they are waiting on some object (their instance itself), and nobody ever notify-es them, using the right instance.
One way to fix this is to have all athlete-s to synchronize/wait/notify on the same object, in example, the JoggingTrack. So that an athlete will wait on the track with track.wait(), and when an athlete is done running, it will call track.notify() , and then a waiting athlete will be waken up.
Then there are other issues as noted by Gabe-
Once you fix the first issue, you will find the race conditions- eg. too many threads all start running even though there are some checks (thereIsSpace) in place.
My question is, could anyone explain to me why something like this does not work and how to handle this problem?
Debugging multithreaded programs is hard. A thread-dump might help and println-debugging might also be helpful however they can cause the problem to migrate so it should be used with caution.
In your case, you are confusing your objects. Think about
Athlete.thereIsSpace() and Athlete.addAthlete(...). Does that make any sense? Does an athlete have space? Do you add an athlete to an athlete? Sometimes the object names don't help you make these sorts of evaluations but in this case, they do. It is the JoggingTrack that has space and that an athlete is added to.
When you are dealing with multiple threads, you need to worry about data sharing. If one thread does track.numOfAthlete++;, how will other threads see the update? They aren't sharing memory by default. Also ++ is actually 3 operations (read, increment, write) and you need to worry about multiple threads running the ++ at the same moment. You will need to use a synchronized block to ensure memory updates or use other concurrent classes such as AtomicInteger or a Semaphore which take care of the locking and data-sharing for you. Also, more generally, you really should not modify another object's fields in this way.
Lastly, you are confused about how wait/notify work. First of all, they only work if they are inside a synchronized block or method so I think the code you've posted won't compile. In your case, the thing that the multiple Athletes are contending for is the JoggingTrack, so the track needs to have the synchronized keyword and not the Athlete. The Athlete is waiting for the JoggingTrack to get space. No one is waiting for the athlete. Something like:
public class JoggingTrack {
public synchronized boolean thereIsSpace() {
return (numOfAthletes < 5);
}
public synchronized void addAthlete() {
numOfAthletes++;
}
...
Also, like the ++ case, you need to be really careful about race conditions in your code. No, not jogging races but programming races. For example, what happens if 2 athletes both go to do the following logic at precisely the same time:
while (!track.thereIsSpace()) {
track.wait();
}
addAthlete();
Both athletes might call thereIsSpace() which returns true (because no one has been added yet). Then both go ahead and add themselves to the track. That would increase the number of athletes by 2 and maybe exceed the 5 limit. These sorts of races-conditions happen every time unless you are in a synchronized block.
The JoggingTrack could instead have code like:
public synchronized void addIfSpaceOrWait() {
while (numOfAthletes >= 5) {
wait();
}
numOfAthletes++;
}
Then the althetes would do:
track.addIfSpaceOrWait();
addAthlete();
This code has no race condition because only one athlete will get the synchronized lock on the track at one time -- java guarantees it. Both of them can call that at the same time and one will return and the other will wait.
Couple other random comments:
You should never do a catch (Exception e) {}. Just doing an e.printStackStrace() is bad enough but not seeing your errors is really going to confuse you ability to debug your program. I will hope you just did that for your post. :-)
I love the JoggingTrack object name but whenever you reference it, it should be joggingTrack or maybe track. Be careful of JoggingTrack s.
An Athlete should not extend thread. It isn't a thread. It should implement Runnable. This is a FAQ.

Java Oracle Example on Guarded Blocks

EDIT: Ok, this is really stupid but I don't know why I didn't see it was a normal loop without the usual increments. I hope I was drunk when I posted this question because now I feel super idiot. Thanks anyway guys!
I'm following some tutorials on Java multi-threading in order to gather as much information and examples as possible.
On the Oracle website there is an official tutorial on Java Concurrency and I am looking at the Guarded Blocks section (here).
Whereas all the concepts are clear, I am reading the Producer/Consumer example at the bottom of the page and I do not understand some parts of the code.
Specifically, in the following is the code for the run() method of the Consumer class, where I do not understand how that for loop is supposed to work. It doesn't even look as it can work to me.
Can anyone explain me?
public void run() {
Random random = new Random();
for (String message = drop.take();
! message.equals("DONE");
message = drop.take()) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
}
It's just for loop being used in a non-idiomatic way.
You have the initialization String message = drop.take(); (instead of int i = 0;).
Then you have the test !message.equals("DONE"); (instead of i < 10).
Finally you have the "increment" or loop-advance or whatever the actual term is. Get the next value with message = drop.take(); (instead of i++).
Maybe it would be easier to understand when converted to a while-loop:
public void run() {
Random random = new Random();
String message = drop.take()
while (!message.equals("DONE")) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
message = drop.take()
}
}
Keep in mind that the for-loop generally consists of three parts:
for (INITIALIZATION; CONDITION; AFTERTHOUGHT)
{
// Code for the for-loop's body goes here.
}
INITIALIZATION is run once before the first iteration, CONDITION is checked prior to every iteration and AFTERTHOUGHT is executed after every iteration.
(Taken from https://en.wikipedia.org/wiki/For_loop#Traditional_for-loops)
So in this example, the INITIALIZATION of the for-loop creates the message variable and takes the first message from drop. It then checks it in the CONDITION block to see if its is anything but DONE. If it is, the loop body is executed once, printing the message and sleeping for up to 5000 milliseconds. Then the next message is taken in the AFTERTHOUGHT clause and the loops checks the CONDITION block again to either print the next message or leave the loop once it receives DONE.

How do I make concurrently running threads?

I want to have two separate threads running two different instances of different classes and I want them to execute the run command at the same time.
I've made a practice class to demonstrate the problem I'm having.
One racer counts forwards, the other counts backwards.
public class testCount {
public static void main(String args[]) {
testCount countCompetition = new testCount();
countCompetition.run();
}
public void run() {
(new Thread(new racer1())).start();
(new Thread(new racer2())).start();
}
public class racer1 implements Runnable {
public void run() {
for(int x = 0; x < 100; x++) {
System.out.println(x);
}
}
}
public class racer2 implements Runnable {
public void run() {
for(int y = 100; y > 0; y--) {
System.out.println(y);
}
}
}
}
My results
1
2
... All the way to 100
100
100
99
... All the way back down
1
What I want
1
100
2
99
3
98
They don't need to be taking turns like that, but they do need to be working at the same time, instead of one after the other.
Any hints, advice or code snippets would be greatly appreciated.
I think all the answers so far are missing the point.
Your existing logic does enable your two threads to both execute concurrently, but this is not evident because your numbers only go up to 100, and the execution will usually stay with a specific thread for more than 1 instruction at a time, otherwise there would be a large amount of overhead in switching between the currently executing thread all the time. In your case, the JVM is deciding to execute your first thread long enough for it to print out 100 numbers before "context switching" to the 2nd thread. The JVM might choose to execute the threads differently, so the result you are seeing is not guaranteed to be the same every time.
If you increase your numbers even to 1000 you will (probably) see the two threads interleaving somewhat. You will still have large runs where one thread prints out a lot of numbers in a row because it is more efficient for the JVM to execute one thread for a while before switching, instead of context switching between every instruction.
Adding Thread.sleep(1) is not a good solution as you are adding an unneccessary delay. Sure, for 100 numbers this might not be noticable but for 10000 numbers you would have a delay of 10 seconds.
Is there any reason that you would require them to interleave to a higher degree than they already do? If there is then your simple model of running two threads concurrently is not sufficient. If not then just let the JVM decide the best order to run your threads in (which in the simple example you have given, means they probably won't interleave most of the time).
Just add Thread.sleep(1); in each racer class after System.out.println().
i.e. it will look like this:
public class racer1 implements Runnable {
public void run() {
for(int x = 0; x < 100; x++) {
System.out.println(x);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
You need to write a basic wait and notify system. One task needs to notify the other that he has fished the work. Basic idea can be derived from below code. create 2 tasks, one to count forward and one to count backward
Runnable task = new Runnable() {
public void run() {
System.out.println("woohooTwo");
synchronized (t) {
while (true) {
System.out.println("---" + Thread.currentThread().getName() + "--" + t.i.getAndIncrement());
t.notifyAll();
try {
Thread.sleep(1000);
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};

Need advice on synchronization of Java Vector / ConcurrentModificationException

In a legacy application I have a Vector that keeps a chronological list of files to process and multiple threads ask it for the next file to process. (Note that I realize that there are likely better collections to use (feel free to suggest), but I don't have time for a change of that magnitude right now.)
At a scheduled interval, another thread checks the working directory to see if any files appear to have been orphaned because something went wrong. The method called by this thread occasionally throws a ConcurrentModificationException if the system is abnormally busy. So I know that at least two threads are trying to use the Vector at once.
Here is the code. I believe the issue is the use of the clone() on the returned Vector.
private synchronized boolean isFileInDataStore( File fileToCheck ){
boolean inFile = false;
for( File wf : (Vector<File>)m_dataStore.getFileList().clone() ){
File zipName = new File( Tools.replaceFileExtension(fileToCheck.getAbsolutePath(), ZIP_EXTENSION) );
if(wf.getAbsolutePath().equals(zipName.getAbsolutePath()) ){
inFile = true;
break;
}
}
return inFile;
}
The getFileList() method is as follows:
public synchronized Vector<File> getFileList() {
synchronized(fileList){
return fileList;
}
}
As a quick fix, would changing the getFileList method to return a copy of the vector as follows suffice?
public synchronized Vector<File> getFileListCopy() {
synchronized(fileList){
return (Vector<File>)fileList.clone();
}
}
I must admit that I am generally confused by the use of synchronized in Java as it pertains to collections, as simply declaring the method as such is not enough. As a bonus question, is declaring the method as synchronized and wrapping the return call with another synchronized block just crazy coding? Looks redundant.
EDIT: Here are the other methods which touch the list.
public synchronized boolean addFile(File aFile) {
boolean added = false;
synchronized(fileList){
if( !fileList.contains(aFile) ){
added = fileList.add(aFile);
}
}
notifyAll();
return added;
}
public synchronized void removeFile( File dirToImport, File aFile ) {
if(aFile!=null){
synchronized(fileList){
fileList.remove(aFile);
}
// Create a dummy list so I can synchronize it.
List<File> zipFiles = new ArrayList<File>();
synchronized(zipFiles){
// Populate with actual list
zipFiles = (List<File>)diodeTable.get(dirToImport);
if(zipFiles!=null){
zipFiles.remove(aFile);
// Repopulate list if the number falls below the number of importer threads.
if( zipFiles.size()<importerThreadCount ){
diodeTable.put(dirToImport, getFileList( dirToImport ));
}
}
}
notifyAll();
}
}
Basically, there are two separate issues here: sycnhronization and ConcurrentModificationException. Vector in contrast to e.g. ArrayList is synchronized internally so basic operation like add() or get() do not need synchronization. But you can get ConcurrentModificationException even from a single thread if you are iterating over a Vector and modify it in the meantime, e.g. by inserting an element. So, if you performed a modifying operation inside your for loop, you could break the Vector even with a single thread. Now, if you return your Vector outside of your class, you don't prevent anyone from modifyuing it without proper synchronization in their code. Synchronization on fileList in the original version of getFileList() is pointless. Returning a copy instead of original could help, as could using a collection which allows modification while iterating, like CopyOnWriteArrayList (but do note the additional cost of modifications, it may be a showstopper in some cases).
"I am generally confused by the use of synchronized in Java as it
pertains to collections, as simply declaring the method as such is not
enough"
Correct. synchronized on a method means that only one thread at a time may enter the method. But if the same collection is visible from multiple methods, then this doesn't help much.
To prevent two threads accessing the same collection at the same time, they need to synchronize on the same object - e.g. the collection itself. You have done this in some of your methods, but isFileInDataStore appears to access a collection returned by getFileList without synchronizing on it.
Note that obtaining the collection in a synchronized manner, as you have done in getFileList, isn't enough - it's the accessing that needs synchronizing. Cloning the collection would (probably) fix the issue if you only need read-access.
As well as looking at synchronizing, I suggest you track down which threads are involved - e.g. print out the call stack of the exception and/or use a debugger. It's better to really understand what's going on than to just synchronize and clone until the errors go away!
Where does the m_dataStore get updated? That's a likely culprit if it's not synchronized.
First, you should move your logic to whatever class is m_dataStore if you haven't.
Once you've done that, make your list final, and synchronize on it ONLY if you are modifying its elements. Threads that only need to read it, don't need synchronized access. They may end up polling an outdated list, but I suppose that is not a problem. This gets you increased performance.
As far as I can tell, you would only need to synchronize when adding and removing, and only need to lock your list.
e.g.
package answer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Example {
public static void main(String[] args)
{
Example c = new Example();
c.runit();
}
public void runit()
{
Thread.currentThread().setName("Thread-1");
new Thread("Thread-2")
{
#Override
public void run() {
test1(true);
}
}.start();
// Force a scenario where Thread-1 allows Thread-2 to acquire the lock
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Example.class.getName()).log(Level.SEVERE, null, ex);
}
// At this point, Thread-2 has acquired the lock, but it has entered its wait() method, releasing the lock
test1(false);
}
public synchronized void test1(boolean wait)
{
System.out.println( Thread.currentThread().getName() + " : Starting...");
try {
if (wait)
{
// Apparently the current thread is supposed to wait for some other thread to do something...
wait();
} else {
// The current thread is supposed to keep running with the lock
doSomeWorkThatRequiresALockLikeRemoveOrAdd();
System.out.println( Thread.currentThread().getName() + " : Our work is done. About to wake up the other thread(s) in 2s...");
Thread.sleep(2000);
// Tell Thread-2 that it we have done our work and that they don't have to spare the CPU anymore.
// This essentially tells it "hey don't wait anymore, start checking if you can get the lock"
// Try commenting this line and you will see that Thread-2 never wakes up...
notifyAll();
// This should show you that Thread-1 will still have the lock at this point (even after calling notifyAll).
//Thread-2 will not print "after wait/notify" for as long as Thread-1 is running this method. The lock is still owned by Thread-1.
Thread.sleep(1000);
}
System.out.println( Thread.currentThread().getName() + " : after wait/notify");
} catch (InterruptedException ex) {
Logger.getLogger(Example.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void doSomeWorkThatRequiresALockLikeRemoveOrAdd()
{
// Do some work that requires a lock like remove or add
}
}

Have threads run indefinitely in a java application

I am trying to program a game in which I have a Table class and each person sitting at the table is a separate thread. The game involves the people passing tokens around and then stopping when the party chime sounds.
how do i program the run() method so that once I start the person threads, they do not die and are alive until the end of the game
One solution that I tried was having a while (true) {} loop in the run() method but that increases my CPU utilization to around 60-70 percent. Is there a better method?
While yes, you need a loop (while is only one way, but it is simplest) you also need to put something inside the loop that waits for things to happen and responds to them. You're aiming to have something like this pseudocode:
loop {
event = WaitForEvent();
RespondToEvent(event);
} until done;
OK, that's the view from 40,000 feet (where everything looks like ants!) but it's still the core of what you want. Oh, and you also need something to fire off the first event that starts the game, obviously.
So, the key then becomes the definition of WaitForEvent(). The classic there is to use a queue to hold the events, and to make blocking reads from the queue so that things wait until something else puts an event in the queue. This is really a Concurrency-101 data-structure, but an ArrayBlockingQueue is already defined correctly and so is what I'd use in my first implementation. You'll probably want to hide its use inside a subclass of Thread, perhaps like this:
public abstract class EventHandlingThread<Event> extends Thread {
private ArrayBlockingQueue<Event> queue = new ArrayBlockingQueue<Event>();
private boolean done;
protected abstract void respondToEvent(Event event);
public final void postEvent(Event event) throws InterruptedException {
queue.put(event);
}
protected final void done() {
done = true;
}
public final void run() {
try {
while (!done) {
respondToEvent(queue.take());
}
} catch (InterruptedException e) {
// Maybe log this, maybe not...
} catch (RuntimeException e) {
// Probably should log this!
}
}
}
Subclass that for each of your tasks and you should be able to get going nicely. The postEvent() method is called by other threads to send messages in, and you call done() on yourself when you've decided enough is enough. You should also make sure that you've always got some event that can be sent in which terminates things so that you can quit the gameā€¦
I would look into Locks and Conditions. This way you can write code that waits for a certain condition to happen. This won't take a lot of CPU power and is even much more efficient and better performing than sleeping .
To make a thread run for an infinite time:
final Object obj = new Object();
try {
Thread th = new Thread(new Runnable() {
public void run() {
synchronized(obj) {
try {
System.out.println("Waiting");
obj.wait();
System.out.println("Done waiting");
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
});
th.start();
System.out.println("Waiting to join.");
// Dont notify; but wait for joining. This will ensure that main thread is running always.
th.join();
System.out.println("End of the Program");
} catch(Exception ex) {
ex.printStackTrace();
}
You may add Thread.sleep() with appropriate time to minimize useless loop iterations.
Another solution is using synchronization. While threads are not required to do anything, they enter into a sleeping state on a monitor using the wait() method, and then when the turn comes, required thread is woken up by the notify() method.
Actor model seems suitable for this scenario. Each person sitting on the table and the table itself can be modelled as actors and the event of passing the tokens and starting and stopping of the game can be modelled as messages to be passed between the actors.
As a bonus, by modelling the scenario as actors you get rid of explicit manipulation of threads, synchronization and locking.
On JVM I will prefer using Scala for modelling actors. For Java you can use libraries like Kilim. See this post for a comparison of Actor model related libraries in Java.
One Way is to use while loop but keep a check i.e
while(true){
if(condition!=true){
Thread.sleep(time);
}else{
break;
}
}
This way if your condition says game is not over it will keep person thread at sleep and memory consumption will be very low.
You should test for a condition in the while loop:
while (!gameOver)
{
do_intersting_stuff();
}
Heavy CPU load is typical for busy wait. Is your loop actually just checking a flag over and over, like
while (!gameOver)
{
if (actionNeeded)
{
do_something();
}
}
you might change to another notification system to sleep and wake up, as this just burns CPU time for nothing.

Categories