I had to make 2 threads that execute alternately and also one of them has to execute N times more than the other.
public void init(int count) {
semaphore1 = new Semaphore(1);
semaphore2 = new Semaphore(0);
num=count;
}
class F1Thread extends Thread {
public void run() {
semaphore1.acquire();
for(int i=0;i<num;i++)
f1();
semaphore2.release();
}
class F2Thread extends Thread {
public void run() {
semaphore2.acquire();
f2();
semaphore1.release();
}
This is my solution but before that i tried acquiring all the permits instead of 1 and doing a loop
public void init(int count) {
semaphore1 = new Semaphore(count);
semaphore2 = new Semaphore(0);
num=count;
}
class F1Thread extends Thread {
public void run() {
semaphore1.acquire(count);
f1();
semaphore2.release();
}
class F2Thread extends Thread {
public void run() {
semaphore2.acquire();
f2();
semaphore1.release(count);
}
My point is
for(int i=0;i<number;i++)
semaphore.acquire();
and
semaphore.acquire(number);
shouldn't perform the same ?
If the semaphore has 5 permits,
10 times acquire() would acquire 5 and block.
acquire(10) would immediately block, till 10 permits are released.
However I did not find this behaviour in the javadocs, nor after eyeing the sources.
It seems that a greedy acquire(number) could mean other threads with a lesser number always pass first.
Unfortunately I did not find a specification.
Related
so much confused why I get a random result while doing 'i++' in a synchronized or a locked method?
public class aaa implements Runnable {
static int count = 0;
public static void main(String[] args) {
aaa aaa = new aaa();
aaa.create();
}
public void create() {
ExecutorService executor = Executors.newFixedThreadPool(100);
for (int i = 0; i < 1000; i++) {
aaa thread = new aaa();
executor.execute(thread);
}
executor.shutdown();
while (true){
if(executor.isTerminated()){
System.out.println("a " + count);
break;
}
}
}
#Override
public void run() {
this.test();
}
public void test() {
Lock lock = new ReentrantLock();
try {
lock.lock();
count++;
System.out.println(count);
} finally {
lock.unlock();
}
}
}
OR:
public synchronized void test() {
count++;
System.out.println(count);
}
the result is a random number sometimes 1000 sometimes 998, 999 ...etc and the print from inside the 'test' method is not in a sequence, it is like :
867
836
825
824
821
820
819
817
816
a 999
However, if it is in a synchronized block, everything looks good:
public void test() {
synchronized (aaa.class) {
count++;
System.out.println(count);
}
}
the result:
993
994
995
996
997
998
999
1000
a 1000
I think all of the methods above should give me the same result 1000, and the self increment should be in a sequence, but only the last method works.What is wrong with the code? Please help!!!
You are creating multiple instances of aaa, each instance creates its own ReentrantLock, and every thread in execution smoothly acquires a lock from its own instance.
public void test() {
Lock lock = new ReentrantLock();
try {
lock.lock();
count++;
System.out.println(count);
} finally {
lock.unlock();
}
}
Since there are multiple instances of aaa, each thread is running on its own instance and the synchronized method uses current object of aaa.class
public synchronized void test() {
count++;
System.out.println(count);
}
The reason for getting a proper result in this approach is, you are using the aaa.class as an object to the synchronization
public void test() {
synchronized (aaa.class) {
count++;
System.out.println(count);
}
}
The solution is, reuse the same lock(ReentrantLock) across all the threads. Defining the lock in the same level as the variable count would solve the issue.
You must create a single mutex, i.e.
static Lock lock = new ReentrantLock();
Your synchronized method does not work since you are creating N aaa instances then, every (non static) method is different (with their own mutex).
Your synchronized (aaa.class) works since aaa.class is the same Object for all aaa instances and methods.
Then, if you need synchronize the method be sure it is the same for all threads, e.g. if test is static will be the same for all
#Override
public void run() {
test();
}
public static synchronized void test() {
count++;
}
but you can inject a "counter class", e.g.
class Counter {
int count = 0;
// non static but synchronized for all (since they use the same `counter` object)
synchronized void inc() {
count++;
}
}
to be used for all threads
...
SyncTest thread = new SyncTest(counter); // <== the same
...
(full code)
public class SyncTest implements Runnable {
private final Counter c;
public SyncTest(Counter c) {
this.c = c;
}
static class Counter {
int count = 0;
// non static but synchronized for all (since they use the same `counter` object)
synchronized void inc() {
count++;
}
}
#Override
public void run() {
test();
}
public void test() {
this.c.inc();
}
public static void main(String[] args) {
// one counter for all
Counter counter = new Counter();
ExecutorService executor = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
SyncTest thread = new SyncTest(counter);
executor.execute(thread);
}
executor.shutdown();
while (true) {
if (executor.isTerminated()) {
System.out.println("a " + counter.count);
break;
}
}
}
}
Rule of thumb: Declare your lock variable on the next line after the variable(s) that you want to protect with it, and declare it with the same keywords. E.g.,
public class aaa implements Runnable {
static int count = 0;
static Lock countLock = new ReentrantLock();
...
If you read deeply enough into any of the other answers here, then you will see why this helps.
I just wrote code for counter problem in a thread. When I add synchronized on Method its working fine but when I use synchronized block inside a method it does not work, why? Something I am missing, I guess.
public class CounterProblem {
class Counter implements Runnable {
private Integer count = 0;
#Override
public void run() {
for(int i = 0; i < 10000; i++) {
increment();
}
}
// THIS GIVES 20000 which is correct every time.
public synchronized void increment() {
count++;
}
// THIS GIVES wrong every time. WHY ?
// public void increment() {
// synchronized(count) {
// count++;
// }
// }
}
public static void main(String[] args) throws InterruptedException {
CounterProblem counterProblem = new CounterProblem();
Counter counter = counterProblem.new Counter();
Thread thread1 = new Thread(counter);
Thread thread2 = new Thread(counter);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.count);
}
}
java.lang.Integer's aren't mutable. When you increment an Integer, you unbox it to a primitive int, increment it, and then autobox the result to a different Integer instance. This means your synchronized block synchronizes on a different object every time, making it pointless - as you've seen yourself.
So my task is this:
Instantiate two object of the same class
Provide a constructor argument, to designate a thread as even and another as odd .
Start both threads right one after other
Odd thread prints odd numbers from 0 to 1000
Even thread prints even numbers from 0 to 1000
However they should be in sync the prints should be 1 , 2 , 3 , 4 .....
One number on each line
However I can't seem to get the locks to release correctly. I've tried reading some of the similar problems on here but they all use multiple classes. What am I doing wrong?
Edit: My main class is doing this -
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
and my output is -
odd: 1
even: 2
...
public class NumberPrinter extends Thread {
private String name;
private int starterInt;
private boolean toggle;
public NumberPrinter(String name) {
super.setName(name);
this.name=name;
if(name.equals("odd")) {
starterInt=1;
toggle = true;
}
else if(name.equals("even")) {
starterInt=2;
toggle = false;
}
}
#Override
public synchronized void run() {
int localInt = starterInt;
boolean localToggle = toggle;
if(name.equals("odd")) {
while(localInt<1000) {
while(localToggle == false)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = false;
notify();
}
}
else {
while(localInt<1000) {
while(localToggle == true)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = true;
notify();
}
}
}
}
The key problem here is that the two threads have no way to coordinate with each other. When you have a local variable (localToggle in this case) nothing outside the method can observe or alter its value.
If you share one object with both threads, however, its state can change, and if used correctly, those state changes will be visible to both threads.
You will see examples where the shared object is an AtomicInteger, but when you use synchronized, wait() and notify(), you don't need the extra concurrency overhead built into the atomic wrappers.
Here's a simple outline:
class Main {
public static main(String... args) {
Main state = new Main();
new Thread(new Counter(state, false)).start();
new Thread(new Counter(state, true)).start();
}
int counter;
private static class Counter implements Runnable {
private final Main state;
private final boolean even;
Counter(Main state, boolean even) {
this.state = state;
this.even = even;
}
#Override
public void run() {
synchronized(state) {
/* Here, use wait and notify to read and update state.counter
* appropriately according to the "even" flag.
*/
}
}
}
}
I'm not clear whether using wait() and notify() yourself is part of the assignment, but an alternative to this outline would be to use something like a BlockingQueue to pass a token back and forth between the two threads. The (error-prone) condition monitoring would be built into the queue, cleaning up your code and making mistakes less likely.
I finally got it working in a way that meets the standards required by my assignment.
Thank you all for your input. I'll leave the answer here for anyone who might need it.
public class Demo {
public static void main(String[] args) {
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
System.out.println("Calling thread Done");
}
public class NumberPrinter extends Thread {
private int max = 1000;
static Object lock = new Object();
String name;
int remainder;
static int startNumber=1;
public NumberPrinter(String name) {
this.name = name;
if(name.equals("even")) {
remainder=0;
}else {
remainder=1;
}
}
#Override
public void run() {
while(startNumber<max) {
synchronized(lock) {
while(startNumber%2 !=remainder) {
try {
lock.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": "+startNumber);
startNumber++;
lock.notifyAll();
}
}
}
}
I'm attempting to edit my program so that the incrementer and decrementer classes are called alternatively, which incrementer being performed first. My aim is to be able to print the value of a shared variable (sharedValue) after each increment/decrement and hopefully see it toggle between 1 and 0. Below is the code for my main class, a semaphore class and incrementer class (there is a class decrementer which is styled the same way as icrementer so i didn't include it).
main class
public class Main extends Thread {
private static int sharedValue = 0;
private static Semaphore semaphore = new Semaphore(1);
static int numberOfCycles = 20000;
public static void increment() {
semaphore.down();
sharedValue++;
semaphore.up();
}
public static void decrement() {
semaphore.down();
sharedValue--;
semaphore.up();
}
public static void main(String[] args) throws InterruptedException {
incrementer inc = new incrementer(numberOfCycles);
inc.start();
inc.join();
decrementer dec = new decrementer(numberOfCycles);
dec.start();
dec.join();
System.out.println(sharedValue);
}
}
Semaphore class
private int count;
// Constructor
public Semaphore(int n) {
count = n;
}
// Only the standard up and down operators are allowed.
public synchronized void down() {
while (count == 0) {
try {
wait(); // Blocking call.
} catch (InterruptedException exception) {
}
}
count--;
}
public synchronized void up() {
count++;
notify();
}
incrementer Class
public class incrementer extends Thread{
private int numberOfIncrements;
public incrementer(int numOfIncrements){
numberOfIncrements = numOfIncrements;
}
public void run(){
for(int i = 0; i <= numberOfIncrements; i++){
Main.increment();
}
}
}
Thanks in advance!
So I have been reading through my notes and it occurred to me that I could use another mutex semaphore which can determine if the buffer is full or empty. Am I right with this approach?
Thread.Join causes your main thread to wait for the completion of the incrementer, then starts the decrementer and then waits for decrementer to complete. If you want them to run concurrently, remove the two Thread.Join calls:
public static void main(String[] args) throws InterruptedException {
incrementer inc = new incrementer(numberOfCycles);
decrementer dec = new decrementer(numberOfCycles);
inc.start();
dec.start();
}
To print the shared value after each increment or decrement, move the println call to the increment and decrement functions of your main class:
public static void increment() {
semaphore.down();
sharedValue++;
System.out.println(sharedValue);
semaphore.up();
}
public static void decrement() {
semaphore.down();
sharedValue--;
System.out.println(sharedValue);
semaphore.up();
}
Also note that even with these changes you won't be observing the toggling between 1 and 0. This is because the two threads don't start at the same time, and even if they did (e.g. using CyclicBarrier) you can't control the scheduling so they would progress differently. If you really want to observe this output, you should make each thread wait for 1ms before and after calling semaphore.up() in order to give the other thread a chance to wait and acquire a permit from the semaphore.
public static void increment() {
semaphore.down();
sharedValue++;
System.out.println(sharedValue);
try {
Thread.sleep(1); //give time to other threads to wait for permit
semaphore.up();
Thread.sleep(1); //give time to other threads to acquire permit
} catch (InterruptedException ex) {
}
}
There are more robust ways to get this kind of output from two threads, but I didn't want to make major modifications to your code.
I'm starting off with a very simple example in multithreading. I'm trying to make a threadsafe counter. I want to create two threads that increment the counter intermittently to reach 1000. Code below:
public class ThreadsExample implements Runnable {
static int counter = 1; // a global counter
public ThreadsExample() {
}
static synchronized void incrementCounter() {
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
}
#Override
public void run() {
while(counter<1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
From what I can tell, the while loop right now means that only the first thread has access to the counter until it reaches 1000. Output:
Thread-0: 1
.
.
.
Thread-0: 999
Thread-1: 1000
How do I fix that? How can I get the threads to share the counter?
You could use the AtomicInteger. It is a class that can be incremented atomically, so two seperate threads calling its increment method do not interleave.
public class ThreadsExample implements Runnable {
static AtomicInteger counter = new AtomicInteger(1); // a global counter
public ThreadsExample() {
}
static void incrementCounter() {
System.out.println(Thread.currentThread().getName() + ": " + counter.getAndIncrement());
}
#Override
public void run() {
while(counter.get() < 1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
Both threads have access to your variable.
The phenomenon you are seeing is called thread starvation. Upon entering the guarded portion of your code (sorry I missed this earlier), other threads will need to block until the thread holding the monitor is done (i.e. when the monitor is released). Whilst one may expect the current thread pass the monitor to the next thread waiting in line, for synchronized blocks, java does not guarantee any fairness or ordering policy to which thread next recieves the monitor. It is entirely possible (and even likely) for a thread that releases and attempts to reacquire the monitor to get hold of it over another thread that has been waiting for a while.
From Oracle:
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. This happens when shared resources are made unavailable for long periods by "greedy" threads. For example, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.
Whilst both of your threads are examples of "greedy" threads (since they repeatedly release and reacquire the monitor), thread-0 is technically started first, thus starving thread-1.
The solution is to use a concurrent synchronization method that supports fairness (e.g. ReentrantLock) as shown below:
public class ThreadsExample implements Runnable {
static int counter = 1; // a global counter
static ReentrantLock counterLock = new ReentrantLock(true); // enable fairness policy
static void incrementCounter(){
counterLock.lock();
// Always good practice to enclose locks in a try-finally block
try{
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
}finally{
counterLock.unlock();
}
}
#Override
public void run() {
while(counter<1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
note the removal of the synchronized keyword in favor of the ReentrantLock within the method. Such a system, with a fairness policy, allows long waiting threads a chance to execute, removing the starvation.
Well, with your code I don't know how to get "exactly" intermittently, but if you use Thread.yield() after call incrementCounter() you will have a better distribution.
public void run() {
while(counter<1000){
incrementCounter();
Thread.yield();
}
}
Otherwise, to get what you propose, you can create two different thread class (ThreadsExample1 and ThreadsExample2 if you want), and another class to be a shared variable.
public class SharedVariable {
private int value;
private boolean turn; //false = ThreadsExample1 --> true = ThreadsExample2
public SharedVariable (){
this.value = 0;
this.turn = false;
}
public void set (int v){
this.value = v;
}
public int get (){
return this.value;
}
public void inc (){
this.value++;
}
public void shiftTurn(){
if (this.turn){
this.turn=false;
}else{
this.turn=true;
}
}
public boolean getTurn(){
return this.turn;
}
}
Now, the main can be:
public static void main(String[] args) {
SharedVariable vCom = new SharedVariable();
ThreadsExample1 hThread1 = new ThreadsExample1 (vCom);
ThreadsExample2 hThread2 = new ThreadsExample2 (vCom);
hThread1.start();
hThread2.start();
try {
hThread1.join();
hThread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
And you have to change your line static int counter = 1; // a global counter
for private SharedVariable counter;
And the new run is:
public void run() {
for (int i = 0; i < 20; i++) {
while (!counter.getTurno()){
Thread.yield();
}
System.out.println(this.counter.get());
this.counter.cambioTurno();
}
}
}
Yes, it is another code, but I think it can help you a little bit.