I am supposed to be using two custom Semaphore classes (binary and counting) to print off letters in an exact sequence. Here is the standard semaphore.
public class Semaphore {
protected int value;
public Semaphore() {
value = 0;
}
public Semaphore(int initial) {
value = (initial >=0) ? initial : 0;
}
public synchronized void P() throws InterruptedException {
while (value==0) {
wait();
}
value--;
}
public synchronized void V() {
value++;
notify();
}
}
And here is the binary semaphore:
public class BinarySemaphore extends Semaphore {
public BinarySemaphore(boolean unlocked) {super(unlocked ? 1 : 0);}
public synchronized void P() throws InterruptedException{
while(value==0) {
wait();
}
value=0;
}
public synchronized void V() {
value=1;
notify();
}
}
Here is the main bulk of the code, except for a reason I can't work out why the threads stop after around thirty or so repetitions. Wait isn't called, the criteria for being true are being reached, so why aren't they working? Any help is much appreciated.
BinarySemaphore binaryWXSemaphore = new BinarySemaphore(false);
BinarySemaphore binaryYZSemaphore = new BinarySemaphore(false);
Semaphore countingWSemaphore = new Semaphore();
Semaphore countingYZSemaphore = new Semaphore();
Runnable runnableW = () -> {
while(true) {
if (binaryWXSemaphore.value == 0 && countingYZSemaphore.value >= countingWSemaphore.value) {
binaryWXSemaphore.V();
countingWSemaphore.V();
System.out.println("W");
}
}
};
Runnable runnableX = () -> {
while(true) {
if (binaryWXSemaphore.value == 1) {
try {
binaryWXSemaphore.P();
System.out.println("X");
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
Runnable runnableY = () -> {
while(true) {
if (binaryYZSemaphore.value == 0 && countingWSemaphore.value > countingYZSemaphore.value) {
binaryYZSemaphore.V();
countingYZSemaphore.V();
System.out.println("y");
}
}
};
Runnable runnableZ = () -> {
while(true) {
if (binaryYZSemaphore.value == 1 && countingWSemaphore.value > countingYZSemaphore.value) {
try {
binaryYZSemaphore.P();
countingYZSemaphore.V();
System.out.println("z");
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
As #iggy points out the issue is related to fact that different threads are reading different values of value, because the way you access it isn't thread safe. Some threads may be using an old copy of the value. Making it volatile will mean each thread access reads more consistent value:
protected volatile int value;
Or switch to AtomicInteger which ensures thread consistent change to the int stored in value. You'll also need to replace the assignments using set/get/inc/decrement methods of AtomicInteger:
protected final AtomicInteger value = new AtomicInteger();
// Then use value.set(0 / 1)
// or value.incrementAndGet / decrementAndGet
Unfortunately, even with the above changes, you may find other issues because value could change in the duration between each Runnable's if statement, and the operations inside those if branches.
Also: replacing notify() by notifyAll() usually gives better multi-thread handling though I don't think this necessarily helps in your example.
I'd like to implement my own semaphore in Java (just for practice, I am aware, that there is Semaphore class)
I have implemented it like that:
public class MySemaphore {
private int value = 1;
public synchronized void take() {
this.value++;
this.notify();
}
public synchronized void release(){
while (this.value == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.value--;
}
}
I am trying to use it in such thread:
public class MyThread extends Thread {
private static MySemaphore semaphore = new MySemaphore();
public void run(){
for (int i = 0; i < 100; i++) {
semaphore.take();
try {
Main.myVariable += 1;
semaphore.release();
} catch (Exception e){
System.out.println("Exception" + e.getMessage());
}
}
}
}
I start and join threads like this:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static int myVariable = 0;
private static int threadsNumber = 100;
public static void main(String[] args) {
List<Thread> allThreads = new ArrayList<>();
for (int i = 0; i < threadsNumber; i++) {
allThreads.add(new Thread(new MyThread()));
}
for (int i = 0; i < threadsNumber; i++) {
allThreads.get(i).start();
}
for (int i = 0; i < threadsNumber; i++) {
try{
allThreads.get(i).join();
} catch (Exception e){
System.out.println(e.getMessage());
System.out.println("********************************");
}
}
System.out.println("Result is " + myVariable);
}
}
I just want to increment a variable 10000 times and receive a result. Without semaphore the result is less than 10000 (like 9923, 9684), which is caused by non-atomicity of incrementation. I want to protect this variable using semaphore.
Unfortunately, the result is still less than or equal to 10000 (but much closer, in 9 out of 10 cases greater than 9990).
Do you have any idea why it happens? Is my semaphore wrong or am doing something wrong with launching threads?
In your MySemaphore class, value is already set to 1. It should be zero because in your release function you are verifying if value equals zero or not. This means that when your program starts, no thread will be able to have the semaphore(because you have set it to 1); doing so, they fall into waiting state. Your program ends when 'threadsNumber' reaches it's limit.In other words, you are not verifying if any thread is in waiting state before the programs ends. This explains why you have a 9/10 as success rate.
My recommendation would be to try setting the value to zero and also verify if there are any threads in waiting state.
Your code be like this:
public class MySemaphore {
private int value = 0; //this is already an error in your code
public synchronized void take() {
this.value++;
this.notify(); // wakes up the first thread that called wait on the shared variable
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.value--;
}
}
right now i'm trying to get my head arround threads and concurrency,
so i tried to make multiple threads which counts together to 1000.
Example: Thread 1=0, Thread 2=1.Thread 3=2, and so on
As you will see in the code i implemented the Runnable interface and started the threads.
What i can see is that every thread starts the loop only for itself even if i use a synchronized method.
This is the loop "class"
private String threadname;
private int counter;
Task3(String threadname,int counter) {
this.threadname = threadname;
this.counter =counter;
}
private synchronized void compute(int i) {
try {
// "simulate" computation
System.out.println(threadname);
Thread.sleep(100);
System.out.println(" " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
for(int i=0; i <= counter;i++)
compute(i);
}
and in this class i start 4 threads with a for loop and give the method aboce the parameters which is only the thread name and how often they should count...
for(int i=0; i<=3;i++){
Runnable r =new Thread(new Task3("Thread"+i,1000));
Thread t = new Thread(r);
t.start();
}
thanks in advance
Explanation
Synchronized only means that it is ensured that a thread waits before entering the method until another thread has finished executing this method. This means that only one thread, at one time, can be inside of this synchronized method.
This can prevent strange behavior when using non-atomic operations. For example threads catching outdated values, thinking they would be up-to-date.
Solution
If you want that all threads count together you need some kind of shared resource, i.e. the counter. Currently every thread has his own counter. You need one counter in total which is shared among all threads.
A quick and dirty method would be to make the counter static. But you can probably do better with a design like this:
Class which manages the threads:
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
for (int i = 0; i < 3; i++) {
Counter counter = new Counter(demo, 1000);
counter.start();
}
}
// Provide a shared resource for all threads
private int sharedCounter = 0;
// Provide a count method for all threads
// which is synchronized to ensure that no
// strange behavior with non-atomic operations occurs
public synchronized void count() {
sharedCounter++;
}
}
And the Thread class:
public class Counter extends Thread {
private Demo mDemo;
private int mAmount;
public Counter(Demo demo, int amount) {
// Remember the shared resource
mDemo = demo;
mAmount = amount;
}
#Override
public void run() {
for (int i < 0; i < mAmount; i++) {
// Call the count method provided
// by the shared resource
mDemo.count();
// Sleep some millis
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I am trying to work around with threads in java. Though I understand that threads output are unpredictable, However was wondering if there is a way to do that.
I have to implement two threads, one prints alphabets(a,b,c...z) and other prints numbers(1,2,3....26). Have to implement it in such a way that the output should be a,1,b,2,c,3,d,4......z,26. Below is my code but it doesn't give the desired output.
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
What tweak should I make in the code to get the desired output? How does synchronization helps here? Or is it really possible when working with Threads at all?
PS: This is not an assignment or some exercise. Its self learning.
It is possible. You need to synchronize it well.
Approach Pseudocode
query some (synchronized) state
state will tell whether nums or chars are allowed
if state allows char and caller will put chars, do it now and change state and wake up waiting threads
if not, wait
if state allows numbers and caller will put numbers, do it now and change state and wake up waiting threads
if not, wait
Java code
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
Output
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24,y,25,z,26,
The whole idea of threads: it represents a "stream of activity" that executes code independent of other threads.
In your case, you want that these two threads go in "lockstep". Thread A does one step, then Thread B, then A, then B.
In order to get there, the two threads need something "synchronize" on - in other words: A sends a signal to B when it has done its steps - and B has to wait for that signal. Then B does its thing, signals to A, ...
For starters, a simple boolean value would do. One thread sets it to true, the other to false (to indicate when it has made its step). Then the thread waits for the boolean to toggle again.
As you intend to learn things, I would just start experimenting from there. In case you want to take detours, look here for example. This might help as well.
HERE IS THE CODE::
You need to create 2 threads and implement wait and notify methods correctly you can also refer "Create two threads, one display odd & other even numbers" for your answer.
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
#Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
#Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Your threads are running at the same time. But not the way you want it, as mentioned above. You will see blocks of data from thread 1 and then a block of data from thread 2; and this is because of thread scheduling. Thread 1 is just queuing its output before thread 2.
To test this theory, increase your output to a 1000 records for example as the alphabet and 26 numbers are not as large to see this.
By doing so, you will see these 'blocks' of data. There is a way to do what you mentioned, but it is not advisable as this is not demonstrating how threads actually work but rather you forcing it to work that way.
With less Code:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}
I am understanding wait() in Java in regards to multithreaded, and as per the documentation, wait() should always be in a loop.
I have difficult in understanding what is the condition we have to give in the loop. Typically, I have seen:
synchornized(obj) {
while(some_condition) {
obj.wait();
}
// some other code
}
I am having difficulty in understanding the "condition" which is used in the loop within which we are keeping wait().
I tried to implement a scenario in which I created two different threads (two different classes implementing Runnable interface), for printing Odd and Even numbers, like: 1 ,2 ,3,4,5,6...
As this is inter-thread communication and we need synchronization, I am having difficulty in relating what is the condition on which I have to keep wait() in loop for these two different threads.
Any clues as to how to decipher this (the condition we keep in loop) greatly appreciated.
Here, maybe this few lines will push you in the right direction, as a follow up to my previous comments.
class LastPrintedMonitor {
public boolean wasLastEven = false;
}
class PrinterOdd implements Runnable {
LastPrintedMonitor monitor;
public PrinterOdd(LastPrintedMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i = 2; i < 40; i += 2) {
synchronized (monitor) {
while (!monitor.wasLastEven) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
monitor.wasLastEven = false;
monitor.notifyAll();
}
}
}
}
class PrinterEven implements Runnable {
LastPrintedMonitor monitor;
public PrinterEven(LastPrintedMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i = 1; i < 40; i += 2) {
synchronized (monitor) {
while (monitor.wasLastEven) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
monitor.wasLastEven = true;
monitor.notifyAll();
}
}
}
}
public class EvenOddPrinterDemo {
public static void main(String[] args) {
LastPrintedMonitor monitor = new LastPrintedMonitor();
Thread odd = new Thread(new PrinterOdd(monitor));
Thread even = new Thread(new PrinterEven(monitor));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done!");
}
}
You mentioned two classes so their synchronized methods will not be synchronized to each other. That's why we synchronized on monitor, as there has to be something that those two objects share to make them "hear" each other.
The looping condition should check whether the execution(threads of the current class) need to be temporarily paused.
Taking an example of famous producer-consumer problem, where in the producer will somehow looks like
synchronized(mySharedObj)
{
while(mySharedObj.length==maxSize)
{
mySharedObj.wait();
}
}
If there are n number of Producer Threads on mySharedObj, all will be waiting when the shared resource(mySharedObj) has reached its limit.