How to make sure that one syncronization block executes after the other - multithreading

I have Counter class with 3 methods out of which 2 are synchronized, I want increment() to execute first and then the count(), so that count for each thread should always be 3000.
Instead of calling the count() from run() I can call it from within increment() is the only approach I can think of, Is there any other way to do So?
class Counter {
int count=0;
void print() {
System.out.println("Print called by: "+Thread.currentThread().getName());
}
synchronized void increment()
{
for(int i=1;i<=3000;i++)
count++;
}
synchronized void getCount() {
System.out.println(count);
count =0;
}
}
class MyThread1 extends Thread {
Counter c;
MyThread1(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}
class MyThread2 extends Thread {
Counter c;
MyThread2(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}
public class Demo {
public static void main(String args[]) {
Counter obj = new Counter();
MyThread1 t1 = new MyThread1(obj);
MyThread2 t2 = new MyThread2(obj);
t1.start();
t2.start();
}
}
Expected O/P in each case:
//The printing of "Print called by:" statement can be in any order as it's not synchronized but the count for each thread should always be 3000
Print called by: Thread-0
Print called by: Thread-1
3000
3000

Working example for my comment (You don't need MyThread1 and MyThread2):
public class Demo {
public static void main(String[] args) {
Counter obj = new Counter();
MyThread t1 = new MyThread(obj);
MyThread t2 = new MyThread(obj);
t1.start();
t2.start();
}
}
class Counter {
private final ThreadLocal<Integer> count = new ThreadLocal<Integer>() {
#Override
protected Integer initialValue() {
return 0;
}
};
void print() {
System.out.println("Print called by: " + Thread.currentThread().getName());
}
void increment() {
for (int i = 1; i <= 3000; i++)
count.set(count.get() + 1);
}
void getCount() {
System.out.println(count.get());
count.set(0);
}
}
class MyThread extends Thread {
Counter c;
MyThread(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
public static void main(String args[]) {
Counter obj = new Counter();
MyThread t1 = new MyThread(obj);
MyThread t2 = new MyThread(obj);
t1.start();
t2.start();
}
}
class Counter {
Lock lock = new ReentrantLock();
int count = 0;
void print() {
System.out.println("Print called by: " + Thread.currentThread().getName());
}
void increment() {
lock.lock();
for (int i = 1; i <= 3000; i++)
count++;
}
void getCount() {
System.out.println(count);
count = 0;
lock.unlock();
}
}
class MyThread extends Thread {
Counter c;
MyThread(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}

You can use synchronized to block a thread.
here the example:
public void run() {
synchronized (Thread.class) {
c.print();
c.increment();
c.getCount();
}
}
synchronized needs an object as param, please use same object for both class MyThread1 and MyThread2
read https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html for more details.

Related

Printing even and odd number by two thread

I am trying to print even and odd number using two different thread but It is throwing IllegalMonitorStateException .Kindly suggest me what am I doing wrong .
package com.rishi.threading;
public class MyThread {
public static class EvenThread extends Thread {
Boolean evenFlag;
Integer sharedCount;
public EvenThread(Boolean flag, Integer count) {
this.evenFlag = flag;
this.sharedCount = count;
}
public void run() {
printEven();
}
private void printEven() {
for (int i = 0; i < 10; i++) {
synchronized (evenFlag) {
if (!evenFlag) {
try {
evenFlag.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
evenFlag = false;
System.out.println("even thread :" + sharedCount++);
notifyAll();
}
}
}
}
public static class OddThread extends Thread {
Boolean evenflag;
Integer sharedCount;
public OddThread(Boolean flag, Integer count) {
this.evenflag = flag;
this.sharedCount = count;
}
public void run() {
printOdd();
}
private void printOdd() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
synchronized (evenflag) {
if (evenflag) {
try {
evenflag.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
evenflag = true;
System.out.println("odd thread :" + sharedCount++);
notifyAll();
}
}
}
}
public static void main(String[] args) {
Boolean evenFlag = new Boolean(true);
Integer sharedCount = new Integer(0);
EvenThread thread1 = new EvenThread(evenFlag, sharedCount);
thread1.setName("evenThread");
OddThread thread2 = new OddThread(evenFlag, sharedCount);
thread2.setName("oddthread");
thread1.start();
thread2.start();
}
}
I created two thread "EvenThread" and "OddThread".
Both the thread shares two common member variable ie evenFlag and sharedCount.
evenFlag -> just a flag which is set as true when sharedCount is even and set as false when shareDcount is set to odd number.
So both the thread is trying to get lock of evenFlag to control the printing of sharedCount.

Implementing custom Executor

In the example below if I implement ExecutorImpl without using Thread, then taskCompletionService.submit is blocked, even though it returns Future.
Is it possible to not block submit, but not use Thread in ExecutorImpl?
class ExecutorServiceTest {
private static class ExecutorImpl implements Executor {
public void execute(Runnable r) {
final Thread t = new Thread(new Runnable() {
public void run() {
r.run();
}});
t.start();
//If used will block others.
//r.run();
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
final Executor executor = new ExecutorImpl();
final CompletionService<String> taskCompletionService = new ExecutorCompletionService<>(executor);
int submittedTasks = 3;
for(int i = 0; i < submittedTasks; i++) {
final int j = i;
//here it is blocked if ExecutorServiceIml doesn't utilize Thread
taskCompletionService.submit(new Callable<String>() {
public String call() throws Exception {
Thread.sleep((3 - j) * 1000);
return "callable:" + String.valueOf(j);
}
});
System.out.println("Task " + String.valueOf(i) + " has been submitted...");
}
for(int tasksHandled=0; tasksHandled < submittedTasks; tasksHandled++) {
try {
final Future<String> result = taskCompletionService.take();
String l = result.get();
System.out.println("Task has completed - result: " + l);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}

Caching Reloading Put Block

how can i block the put method when cache reloading is being called.
Example: These are dummy classes not the actual.
Caching class
public class Class1 {
private static Map<Integer, Integer> map = new HashMap<>();
public Class1() {
for (int i = 0; i < 20; i++) {
map.put(i, ++i);
}
}
public void reload() throws InterruptedException {
Map<Integer, Integer> exist = map;
System.out.println("are you waiting ");
System.out.println("waiting over");
map = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : exist.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
for (int i = 100; i < 120; i++) {
map.put(i, ++i);
}
}
public Map<Integer, Integer> getMap() {
return map;
}
}
Class initializing the cache
public class Class2 {
private static Class1 cache = new Class1();;
public Class1 getCache() {
return cache;
}
public void reload() throws InterruptedException {
cache.reload();
}
}
class using the cache
package com.diaryreaders.corejava.algorithms.dp;
public class Class3 {
public static void main(String[] args) {
final Class2 klass = new Class2();
Runnable runn1 = new Runnable() {
#Override
public void run() {
int i = 50, j = 50;
while (i < 100) {
System.out.println("I am stuck due to lock");
klass.getCache().getMap().put(i++, j++);
System.out.println(klass.getCache().getMap());
}
}
};
Runnable runn2 = new Runnable() {
#Override
public void run() {
try {
System.out.println("Calling reloading");
klass.reload();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runn1);
Thread t2 = new Thread(runn2);
t1.start();
t2.start();
}
}
As thread t2 is calling reloading, t1 should be blocked i.e cache put method be blocked till reloading completes

PingPong Program Java Multithreading

I am trying to learn basic concept of Multi Threading.
Why my ping pong program prints only Ping0 & Pong0, Why notify() does not start the Ping Thread which is in Wait state?
public class PingPong implements Runnable {
String word;
public PingPong(String word) {
this.word = word;
}
public void run() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
wait();
notifyAll();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) {
Runnable p1 = new PingPong("ping");
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong");
Thread t2 = new Thread(p2);
t2.start();
}
}
Output
ping0
pong0
I tried removing wait() and it's printing ping pong till the end of loop. but is this guaranteed that it will print in sequence?
Why wait() followed by notify() does not ask the ping1 thread to start execution?
If you see the jstack, you can see thread-0 and thread-1 are waiting for different lock. That's because your p1 and p2 are different objects, so when you use synchronized (this), they are not competing for the same lock, so notify this way won't work. try use another object as the lock.
wait need to run after notify. As when both threads go into waiting stat, no other threads can notify them.
try this code:
String word;
Object a;
public PingPong(String word, Object a) {
this.word = word;
this.a = a;
}
public void run() {
synchronized (a) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
a.notifyAll();
a.wait();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Runnable p1 = new PingPong("ping", a);
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong", a);
Thread t2 = new Thread(p2);
t2.start();
}
Here is a similar solution using Thread Pool Executors:
public class PingPong implements Runnable {
String word;
Lock lock;
public PingPong(String word, Lock lock) {
this.word = word;
this.lock = lock;
}
#Override
public void run() {
while(true){
System.out.println("Received : " + word);
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(2);
Lock lock = new ReentrantLock();
while(true){
ex.submit(new PingPong("ping", lock));
ex.submit(new PingPong("pong", lock));
}
}
}
Below solution based on:
Java internal API
order of execution
public class Test {
public static void main(String[] args) {
SynchronousQueue<String> queue = new SynchronousQueue<>();
Thread ping = new Thread(new Task(queue, "ping", "ping"));
ping.setName("ping thread");
ping.start();
Thread pong = new Thread(new Task(queue, "pong", "ping"));
pong.setName("pong thread");
pong.start();
}
private static class Task implements Runnable {
private SynchronousQueue<String> queue;
private String command;
private String step;
Task(SynchronousQueue<String> queue, String command, String step) {
this.queue = queue;
this.command = command;
this.step = step;
}
#Override
public void run() {
try {
if (command.equals(step)) {
doCommandAndWaitRepeatedly();
} else {
waitAndDoCommandRepeatedly();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void doCommandAndWaitRepeatedly() throws InterruptedException {
while (true) {
queue.offer(command, 1, TimeUnit.SECONDS);
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS));
}
}
private void waitAndDoCommandRepeatedly() throws InterruptedException {
while (true) {
System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS));
Thread.sleep(500);
queue.offer(command, 1, TimeUnit.SECONDS);
}
}
}
}
class Ping extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("PING");
try{
sleep(2000);
} catch(Exception e){}
}
}
}
class Pong extends Thread
{
public void run()
{
for (int i=1;i<=5;i++)
{
System.out.println("PONG");
try{
sleep(2000);
} catch(Exception e){}
}
}
}
public class PingPong
{
public static void main(String... args) throws Exception
{
Ping p1=new Ping();
Pong p2=new Pong();
p1.start();
Thread.sleep(1000); //super important for proper sequence
p2.start();
p1.join();
}
}

Thread synchronization with multiple objects

I have been facing this problem for many days, Please help me out. I am implementing producer-consumer example using thread synchronization. I have made some twist in this traditional program. Instead of using only one queue object, i have used two Queue objects. But program is not working.. (PS- I know i can make this program work by using only one object of queue, But what if i want to use two queue objects ?? )
class Queue {
static int value;
static boolean valueSet = false;
public static final Object obj;
static {
obj = new Object();
}
void push() {
synchronized(Queue.obj) {
while( Queue.valueSet ) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
System.out.print("\n\n Push:- " + (++(Queue.value)));
Queue.valueSet = true;
return;
}
}
void pop() {
synchronized(Queue.obj) {
while(!(Queue.valueSet)) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
System.out.print("\n\n Pop:- " + Queue.value);
Queue.valueSet = false;
return;
}
}
}
class Producer implements Runnable {
Queue Q;
Thread P;
Producer(Queue Q) {
this.Q = Q;
P = new Thread(this);
P.start();
}
public void run() {
while(true) {
Q.push();
}
}
}
class Consumer implements Runnable {
Queue Q;
Thread C;
Consumer(Queue Q) {
this.Q = Q;
C = new Thread(this);
C.start();
}
public void run() {
while(true) {
Q.pop();
}
}
}
public class TestQueue {
public static void main(String[] args) {
Queue Q1 = new Queue();
Queue Q2 = new Queue();
Object obj = new Object();
Producer p = new Producer(Q1);
Consumer c = new Consumer(Q2);
}
}
I got the answer. My misconception was wait,notify and notifyall methods are of thread class. So i was invoking them on thread object.
Solution is to just invoke wait and notify method on shared static object other than thread.
Answer:-
class Queue {
static int value;
static boolean valueSet = false;
public static final Object obj;
static {
obj = new Object();
}
void push() {
synchronized(Queue.obj) {
while( Queue.valueSet ) {
try {
Queue.obj.wait();
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
}
System.out.print("\n\n Push:- " + (++(Queue.value)));
Queue.valueSet = true;
Queue.obj.notify();
}
}
void pop() {
synchronized(Queue.obj) {
while(!(Queue.valueSet)) {
try {
Queue.obj.wait();
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
}
System.out.print("\n\n Pop:- " + Queue.value);
Queue.valueSet = false;
Queue.obj.notify();
}
}
}
class Producer implements Runnable {
Queue Q;
Thread P;
Producer(Queue Q) {
this.Q = Q;
P = new Thread(this);
P.start();
}
public void run() {
while(true) {
Q.push();
}
}
}
class Consumer implements Runnable {
Queue Q;
Thread C;
Consumer(Queue Q) {
this.Q = Q;
C = new Thread(this);
C.start();
}
public void run() {
while(true) {
Q.pop();
}
}
}
public class TestQueue {
public static void main(String[] args) {
Queue Q1 = new Queue();
Queue Q2 = new Queue();
Producer p = new Producer(Q1);
Consumer c = new Consumer(Q2);
}
}

Resources