Java Multithreading - Threadsafe Counter - java

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.

Related

Solving Counter Problem in Java Thread With synchronized method and block

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.

How To Lock A block of code for a Thread in Java

consider the below code.
public class MyThread extends Thread {
int limit;
public MyThread(int limit, String name) {
super();
this.limit = limit;
this.setName(name);
}
public void run() {
printValues();
}
private synchronized void printValues() {
for (int i = 1; i < limit; i++) {
System.out.println(currentThread().getName() + " No = " + i);
}
}
}
Requirement: If a thread starts execution of printValues(), suppose it has to print till 10000. Until it completes its job, no other thread should be able to enter this method.
For this I tried Lock interface as well not able to achieve this.
can anyone throw some inputs on this?
You time will be highly appreciated.
Putting synchronized means a thread has to acquire the lock (monitor) for the object instance. If you enforce only one instance of the object it stops concurrent execution.
Alternatively you can have a static lock to do the same thing
private static final Object lock = new Object();
public void printValues() {
synchronized(lock) {
//...
}
}

Alternate between two threads (producer-consumer)

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.

Synchronized methods to avoid deadlock

I have two synchronized methods and I'm using the mediator design pattern.
I'm trying to avoid deadlocks, which is (from what I understand) for example when a thread has a lock on a variable res1 but needs a lock on variable res2. The other thread needs the lock for res1 but has the lock for res2 - resulting in a deadlock, right?
Assuming my understanding of deadlocks are correct, then my question is whether or not I have solved the issue of deadlock in this code?
I have two synchronized methods and two threads.
public class Producer extends Thread {
private Mediator med;
private int id;
private static int count = 1;
public Producer(Mediator m) {
med = m;
id = count++;
}
public void run() {
int num;
while(true) {
num = (int)(Math.random()*100);
med.storeMessage(num);
System.out.println("P-" + id + ": " + num);
}
}
}
public class Consumer extends Thread {
private Mediator med;
private int id;
private static int count = 1;
// laver kopling over til mediator
public Consumer(Mediator m) {
med = m;
id = count++;
}
public void run() {
int num;
while(true) {
num = med.retrieveMessage();
System.out.println("C" + id + ": " + num);
}
}
}
public class Mediator {
private int number;
private boolean slotFull = false;
public synchronized void storeMessage(int num) {
while(slotFull == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
slotFull = true;
number = num;
notifyAll();
}
public synchronized int retrieveMessage() {
while(slotFull == false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
slotFull = false;
notifyAll();
return number;
}
}
public class MediatorTest {
public static void main(String[] args) {
Mediator mb = new Mediator();
new Producer(mb).start();
new Producer(mb).start();
new Producer(mb).start();
new Consumer(mb).start();
new Consumer(mb).start();
}
}
for example when a thread has a lock on a variable res1 but needs a lock on variable res2
What matters is not that there are two variables, what matters is that there must be two (or more) locks.
The names "res1" and "res2" are meant to suggest two resources each of which may have one or more variables, and each of which has its own lock. Here's where you get into trouble:
final Object lock1 = new Object();
final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
// Call Thread.sleep(1000) here to simulate the thread losing its time slice.
synchronized(lock2) {
doSomethingThatRequiresBothLocks
}
}
}
public void method2() {
synchronized (lock2) {
// Do the same here 'cause you can't know which thread will get to run first.
synchronized(lock1) {
doSomethingElseThatRequiresBothLocks()
}
}
}
If thread A calls method1(), there is a very small chance that it could lose its time slice (i.e., turn to run) just after it successfully locks lock1, but before it locks lock2.
Then, while thread A is waiting its turn to run again, thread B calls method2(). Thread B will be able to lock lock2, but then it gets stuck because lock1 is locked by thread A. Furthermore, when thread A gets to run again, it will immediately be blocked when it tries to lock lock2 which is owned by thread B. Neither thread will ever be able to continue from that point.
In real code, it's never so obvious. When it happens in real-life, it usually is because of some unforseen interaction between code from two or more different modules that may not even be aware of each other, but which access the same common resources.
Your understanding of the basic deadlock problem is correct. With your second question about validity of your solution to the deadlock problem, you've only got 1 lock, so I'd say "yes" by default, since the deadlock you described isn't possible in this situation
I agree with what #ControlAltDel has said. And your understanding of a deadlock matches mine. Whereas there are a few different ways in which a deadlock can manifest itself, the way you describe -- inconsistently acquiring multiple monitors by involved threads (methods) causes deadlock.
Another way would be to (for example,) sleep while holding a lock. As you coded correctly, when the producer finds that slotFull = true, it waits, giving up the lock, so the other thread (consumer, which is sharing the same instance of Mediator with producer) can make progress potentially causing this thread also to make progress after it gets a notification. If you had chosen to call Thread.sleep() instead (naively hoping that someone will cause the sleep to end when the condition would be false), then it would cause a deadlock because this thread is sleeping, still holding the lock, denying access to the other thread.
Every object has one lock which restrict multiple threads to access same block of code or method when you use synchronized keyword.
Coming to your problem, it will not deadlock.
If you have two independent attribute in a class shared by multiple threads, you must synchronized the access to each variable, but there is no problem if one thread is accessing one of the attribute and another thread accessing the other at the same time.
class Cinema {
private long vacanciesCinema1; private long vacanciesCinema2;
private final Object controlCinema1, controlCinema2;
public Cinema() {
controlCinema1 = new Object();
controlCinema2 = new Object();
vacanciesCinema1 = 20;
vacanciesCinema2 = 20;
}
public boolean sellTickets1(int number) {
synchronized (controlCinema1) {
if (number < vacanciesCinema1) {
vacanciesCinema1 -= number;
return true;
} else {
return false;
}
}
}
public boolean sellTickets2(int number) {
synchronized (controlCinema2) {
if (number < vacanciesCinema2) {
vacanciesCinema2 -= number;
return true;
} else {
return false;
}
}
}
public boolean returnTickets1(int number) {
synchronized (controlCinema1) {
vacanciesCinema1 += number;
return true;
}
}
public boolean returnTickets2(int number) {
synchronized (controlCinema2) {
vacanciesCinema2 += number;
return true;
}
}
public long getVacanciesCinema1() {
return vacanciesCinema1;
}
public long getVacanciesCinema2() {
return vacanciesCinema2;
}
}
class TicketOffice1 implements Runnable {
private final Cinema cinema;
public TicketOffice1(Cinema cinema) {
this.cinema = cinema;
}
#Override
public void run() {
cinema.sellTickets1(3);
cinema.sellTickets1(2);
cinema.sellTickets2(2);
cinema.returnTickets1(3);
cinema.sellTickets1(5);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
}
}
public class CinemaMain {
public static void main(String[] args) {
Cinema cinema = new Cinema();
TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");
TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Room 1 Vacancies: %d\n", cinema.getVacanciesCinema1());
System.out.printf("Room 2 Vacancies: %d\n", cinema.getVacanciesCinema2());
}
}

synchronized method while using wait()

I ran the following code:
class Counter extends Thread {
static int i=0;
//method where the thread execution will start
public void run(){
//logic to execute in a thread
while (true) {
increment();
}
}
public synchronized void increment() {
try {
System.out.println(this.getName() + " " + i++);
wait(1000);
notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//let’s see how to start the threads
public static void main(String[] args){
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.setName("Thread1");
c2.setName("Thread2");
c1.start();
c2.start();
}
}
The result of this code was (added line numbers):
1: Thread1 0
2: Thread2 1
3: Thread2 2
4: Thread1 3
5: Thread2 4
6: Thread1 4
7: Thread1 5
8: Thread2 6
stopping...
Since increment method is synchronized and since it contains wait(1000) I didnt expect:
1. Thread2 to print 2 consecutive prints: lines 2,3
I expected the threads to interleave their prints
2. on lines 5,6 the i remains 4.
could anyone give me an explanation for this?
Synchronized instance methods like this:
public synchronized void foo() {
...
}
are roughly equivalent to:
public void foo() {
synchronized(this) {
...
}
}
Do you see the problem here? The synchronization is done on the current instance.
Since you are creating two separate Thread objects each increment method will synchronize on a different object, thus rendering the lock useless.
You should either make your increment method static (thus the locking is done on the class itself) or use a static lock object:
private static final Object locker = new Object();
public void foo() {
synchronized(locker) {
...
}
}
And one final advice: the preferred way to create a thread in java is by implementing Runnable, not extending Thread.
You are only synchronizing at the instance level. To synchronize across all Counter instances you need the increment method to be static as well as synchronized.
As it stands all your threads run freely, concurrent with each other, because they share no synchronization mechanism.
This is probably the code you are looking for
class Counter implements Runnable {
static int i = 0;
private Lock lock;
private Condition condition;
public Counter(Lock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
public void run() {
while (true) {
lock.lock();
try {
condition.await(1, TimeUnit.SECONDS);
System.out.append(Thread.currentThread().getName()).append(" ").println(i++);
condition.signalAll();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
Lock lock = new ReentrantLock(true);
Condition condition = lock.newCondition();
Executor e = Executors.newFixedThreadPool(2);
e.execute(new Counter(lock, condition));
e.execute(new Counter(lock, condition));
}
}

Categories

Resources