I have created a singleton instance which i am getting in my two threads, one thread, i.e, AddEmployeeInfo is adding the employee details into ArrayList and notifies the other thread, i.e., DisplayEmployeeInfo which displays all the employee information which are added and then waits for further data,
please help me with what changes should i include to make it work and proper inter thread communication is being done :
class AddEmployeeInfo implements Runnable{
SingletonInstance inst;
public AddEmployeeInfo(SingletonInstance instance) {
inst = instance;
}
#Override
public void run() {
Employee e1 = new Employee();
e1.setEmpId(001);
e1.setEmpName("SK");
e1.setEmpExp(2);
inst.addEmployee(e1);
Employee e2 = new Employee();
e2.setEmpId(002);
e2.setEmpName("AMIT");
e2.setEmpExp(3);
inst.addEmployee(e2);
}
}
class DisplayEmployeeInfo implements Runnable{
SingletonInstance inst;
public DisplayEmployeeInfo(SingletonInstance instance) {
inst = instance;
}
#Override
public void run() {
while(true){
inst.displayEmployeeInfo();
}}}
public class EmployeeInfo {
public static void main(String[] args) {
SingletonInstance instance = new SingletonInstance();
Thread t1 = new Thread(new AddEmployeeInfo(instance));
Thread t2 = new Thread(new DisplayEmployeeInfo(instance));
t1.start();
t2.start();
}
}
class SingletonInstance{
public List<Employee> empDetails = new ArrayList<>();
boolean flag = false;
public synchronized void addEmployee(Employee emp){
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
notify();
empDetails.add(emp);
}
public synchronized void displayEmployeeInfo() {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(Employee getDetails : empDetails){
System.out.println(getDetails.getEmpId() + " " + getDetails.getEmpName());
}
flag = false;
notify();
}
}
Related
I was trying the wait and notify scenario, getting --> Exception in thread "Thread-1" java.lang.IllegalMonitorStateException when calling notify.
wait method releases the lock, so the threadB can execute the and from threadB i'm calling lock.notify for threadA.
Could you help me on this?
class SynchronizedCodee {
int a = 5;
Lock lock = new ReentrantLock();
public void threadA()
{
lock.lock();
try {
lock.wait();
System.out.println("A = "+a);
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
finally
{
lock.unlock();
}
}
public void threadB()
{
if(lock.tryLock())
{
this.a = 11;
System.out.println("B = "+a);
lock.notify(); // getting erro over here
}
else
{
System.out.println("didn't managed to get a lock");
}
}
}
class ThreadA extends Thread{
SynchronizedCodee s;
public ThreadA(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadA();
}
}
class ThreadB extends Thread{
SynchronizedCodee s;
public ThreadB(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadB();
}
}
public class SynchronizedCode{
public static void main(String ag[]) throws InterruptedException
{
SynchronizedCodee s = new SynchronizedCodee();
ThreadA t1 = new ThreadA(s);
ThreadB t2 = new ThreadB(s);
t1.start();
Thread.sleep(100);
t2.start();
}
}
You are calling wait and notify on explicit lock objects and that is not legal. If you are using explicit lock objects, you have to use Condition object associated with it. Then you should call condition.await and condition.signalAll methods instead of wait and notify. Here's the idiom for using explicit locks in your particular scenario.
final Condition setA = lock.newCondition();
public void threadA() {
lock.lock();
try {
while (a == 5)
setA.await();
System.out.println("A = " + a);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public void threadB() {
lock.lock();
try {
this.a = 11;
System.out.println("B = " + a);
setA.signalAll();
} finally {
lock.unlock();
}
}
And this program produces the following output:
B = 11
A = 11
Today I was doing some practice on Thread and was trying to create one Even Odd number program. I created this using synchronized and it was working fine.
But when I tried to do the same thing using Lock then I stuck.
Below is the code that I am trying to do the same.
public class OddEvenNumberThreadLock {
public static void main(String args[]) {
SharedObject sharedObject = new SharedObject();
Thread evenThread = new Thread(new EvenNumber(sharedObject));
Thread oddThread = new Thread(new OddNumber(sharedObject));
evenThread.start();
oddThread.start();
}
}
class EvenNumber implements Runnable {
SharedObject object;
public EvenNumber(SharedObject object) {
this.object = object;
}
#Override
public void run() {
for (int i = 0; i <= 100; i = i + 2) {
while (!object.isOdd()) {
object.getLock().lock();
try {
System.out.println("Even : " + i);
object.setOdd(true);
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
}
class OddNumber implements Runnable {
SharedObject object;
public OddNumber(SharedObject object) {
this.object = object;
}
#Override
public void run() {
for (int i = 1; i <= 100; i = i + 2) {
while (object.isOdd()) {
object.getLock().lock();
try {
System.out.println("Odd : " + i);
object.setOdd(false);
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
}
class SharedObject {
private Lock lock;
private boolean isOdd;
public SharedObject() {
this.lock = new ReentrantLock();
}
public boolean isOdd() {
return isOdd;
}
public void setOdd(boolean isOdd) {
this.isOdd = isOdd;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
}
I have one more question there like in the case of synchronized we use notify method to inform other thread. How we can achieve this thing in case of Lock.
Thanks
As far as I can tell you want to achieve that the two threads of yours print even and odd numbers in a ping-pong style. The behavior you want is easier to achieve with ReentrantLock than with synchronized block since synchronized is always unfair, but you can make ReentrantLock to be fair using the aproppriate constructor. Here is how your program would look like with Locks:
public class App {
public static void main(String args[]) {
SharedObject sharedObject = new SharedObject();
Thread evenThread = new Thread(new EvenNumber(sharedObject));
Thread oddThread = new Thread(new OddNumber(sharedObject));
evenThread.start();
oddThread.start();
}
}
class EvenNumber implements Runnable {
SharedObject object;
public EvenNumber(SharedObject object) {
this.object = object;
}
public void run() {
int i = 0;
while(i <= 100) {
object.getLock().lock();
try {
if (!object.isOdd()) {
System.out.println("Even : " + i);
i = i + 2;
object.setOdd(true);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
class OddNumber implements Runnable {
SharedObject object;
public OddNumber(SharedObject object) {
this.object = object;
}
public void run() {
int i = 1;
while(i <= 100) {
object.getLock().lock();
try {
if(object.isOdd()) {
System.out.println("Odd : " + i);
i = i + 2;
object.setOdd(false);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
class SharedObject {
private Lock lock;
private boolean isOdd;
public SharedObject() {
this.lock = new ReentrantLock(true);
}
public boolean isOdd() {
return isOdd;
}
public void setOdd(boolean isOdd) {
this.isOdd = isOdd;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
}
I'm trying to interleave the execution of two independent threads. such that both have a run method with 10 iterations and after every iteration i want to context switch the threads.
thread A starts and after doing something like printing passes control to thread B. then thread B prints and passes control back to A and so on until both finish.
What is the effective mechanism to do this?
I'm attaching a sample code. hope you can help.
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
//SuspendResume.suspendFlag2=false;
SuspendResume.suspendFlag1=true;
while(SuspendResume.suspendFlag1) {
wait();
//System.out.println(SuspendResume.ob1.t.getState().toString());
// if(SuspendResume.ob2.t.getState().toString()=="WAITING")
// SuspendResume.ob2.t.notify();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class NewThread2 implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread2(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
synchronized(this) {
//SuspendResume.suspendFlag1=false;
//while(SuspendResume.suspendFlag1) {
// while(suspendFlag) {
//wait();
//System.out.println(SuspendResume.ob2.t.getState().toString());
//if(SuspendResume.ob1.t.getState().toString()=="WAITING")
//SuspendResume.ob1.t.notify();
//}
SuspendResume.suspendFlag1=false;
notify();
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class SuspendResume {
static boolean suspendFlag1=false;
static NewThread ob1 = new NewThread("One");
static NewThread2 ob2 = new NewThread2("Two");
// static boolean suspendFlag2=false;
public static void main(String args[]) {
try {
//Thread.sleep(1000);
//ob1.mysuspend();
//System.out.println("Suspending thread One");
//Thread.sleep(1000);
//ob1.myresume();
//System.out.println("Resuming thread One");
// ob2.mysuspend();
//System.out.println("Suspending thread Two");
Thread.sleep(1000);
// ob2.myresume();
//System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
System.out.println(ob1.getState());
System.out.println(ob1.getState());
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
First off, I'm not sure what kind of scenario you have where you want to run two threads sequentially over and over again. That sounds like a single thread running two different methods in a loop. None-the-less, it sounds like an interesting challenge so I took it up.
Making use of Java 5's Exchanger class, the solution gets pretty small. I ended up with a single Runnable class. I use two instances of them to pass around a boolean true and boolean false to each other. The Exchanger class facilitates the passing around of the boolean values in a thread safe manner. A Runnable only 'executes' its code when it has the boolean true value.
package interleavedexample;
import java.util.concurrent.Exchanger;
import java.util.logging.Logger;
/**
*
*/
public class InterleavedRunnable implements Runnable {
private final String name;
private final Exchanger<Boolean> exchanger;
private Boolean state;
public InterleavedRunnable(String name, Exchanger<Boolean> exchanger,
Boolean state) {
this.name = name;
this.exchanger = exchanger;
this.state = state;
}
#Override
public void run() {
try {
while (true) {
if (state) {
Logger.getLogger(getClass().getName()).info(name + " is running");
}
state = exchanger.exchange(state);
}
} catch (InterruptedException ex) {
Logger.getLogger(name).info("Interrupted");
}
}
Setting up the runnables are quite easy:
public static void main(String[] args) {
Exchanger<Boolean> exchanger = new Exchanger<Boolean>();
Thread thread1 = new Thread(new InterleavedRunnable("Thread 1", exchanger, true));
Thread thread2 = new Thread(new InterleavedRunnable("Thread 2", exchanger, false));
thread1.start();
thread2.start();
}
Anytime you can find existing functionality within the Java API (or well known libraries), you should utilize them to the fullest extent. The less lines of code you write the less lines there are to maintain.
The 'OS Sycnro 101' solution is to use two semaphores, one for each thread, and swap over one 'GO' token/unit between them. Start both threads and then give the token to whichever thread you want to go first.
Use wait and notify for this.
public class Thread1 implements Runnable {
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("1");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Thread2 implements Runnable{
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("2");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Main {
public volatile static Object obj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
Thread t1 = new Thread(new Thread1());
Thread t2 = new Thread(new Thread2());
t1.start();
t2.start();
synchronized (obj) {
obj.notifyAll();
}
}
}
Did not get your question correctly. If you want to execute thread B only after thread A execution is over, then there is no point of multi-threading at all. You can simply put the thread B contents in thread A run() method.
Still if it is very much required then you can try using wait() and notify() methods on two objects . Something like this.
Class ClassA implements runnable{
Message messageA;
Message messageB;
public ClassA(Message messageA,,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop contition;){
//code here
messageB.notify();
messageA.wait();
}
}
}
Class ClassB implements runnable{
Message messageA;
Message messageB;
public ClassB(Message messageA,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop condition;){
messageB.wait();
//code here
messageA.notify();
}
}
}
now create two objects in main messageA and messageB and pass both of them in the constructor of each thread.
Sorry if this a bit of a basic question but I've been thinking about doing multiple sprite loops and for the first time I tried to create two threads in main, both with while(true) loops. My intention: to have two threads looping simultaneously. However when I run the program it seems to interrupt the flow of execution and the second loop doesn't getting executed in a new thread but just stops with the program stuck on the first endless while() loop of a thread. I think it is still just executing the main thread rather than starting a new one and then continuing on.
I've tried it two ways:
Once with Threads:
public class Zzz {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
r1 r = new r1();
r2 a = new r2();
r.start();
a.start();
}
}
public class r1 extends Thread {
#Override
public void start() {
while(true) {
System.out.println("r1");
try {
this.sleep(100);
} catch (Exception ex) {
}
}
}
}
public class r2 extends Thread {
#Override
public void start() {
while(true) {
System.out.println("r2");
try {
this.sleep(100);
} catch (Exception ex) {
}
}
}
}
And once with Runnable:
public class Zzz {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
r1 r = new r1();
r2 a = new r2();
r.run();
a.run();
}
}
public class r1 implements Runnable {
#Override
public void run() {
while(true) {
System.out.println("r1");
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
}
public class r2 implements Runnable {
#Override
public void run() {
while(true) {
System.out.println("r2");
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
}
But to no avail. It always gets stuck at R1. Any ideas anyone? I've googled and looked around about threads and I can't find this covered anywhere.
You need to override run method & in case of runnable you need to create instance of Thread
public class MyThread extends Thread{
#Override
public void run() {
while(true) {
System.out.println("My Thread running");
}
}
ánd for the case of Runnable
class MyRunnable implements Runnable{
public void run(){
System.out.println("I am executing by Thread: " + Thread.currentThread().getName());
}
}
and
Thread mythread = new MyThread();
mythread.setName("T1");
Thread myrunnable = new Thread(new MyRunnable());
myrunnable.start();
To start threads, you need to create two Threads from the Runnables and start them:
Thread t1 = new Thread(r);
Thread t2 = new Thread(a);
t1.start();
t2.start();
Define classes r1 and r2 as :
public class Thread1 extends Thread {
#Override
public void run() {
System.out.println("r1");
try {
this.sleep(100);
} catch (Exception ex) {
}
}
}
public class Thread2 extends Thread {
#Override
public void run() {
System.out.println("r2");
try {
this.sleep(100);
} catch (Exception ex) {
}
}
}
public class ThreadTester {
public static void main(String[] args) {
Thread1 r = new Thread1();
Thread2 a = new Thread2();
r.start();
a.start();
}
}
Using Runnable :
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
check java documentation for more info
I have this code:
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
Where the calling class implements a method that calls notifyAll() on synchObj when WorkerThread instance is done. Everything works pretty much as expected except the final call to System.out.println("End"); is never called. Why is that?
Edit: Here's the rest of the code:
public class App implements Notifee {
private boolean isDone = false;
private final Object synchObj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
App app = new App();
for (int i = 0; i < 5; i++) {
try {
app.doSomething();
} catch (InterruptedException e) {
System.err.println("Didn't even start");
e.printStackTrace();
}
}
}
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
#Override
public void letMeKnow() {
synchronized (synchObj) {
synchObj.notifyAll();
}
}
}
public class WorkerThread extends Thread {
private Notifee n;
public WorkerThread(Notifee n){
this.n = n;
}
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
n.letMeKnow();
}
}
You are never setting isDone to true. Also you should make it volatile. You probably should add:
#Override
public void letMeKnow() {
isDone = true;
synchronized (synchObj) {
synchObj.notifyAll();
}
}
Edit: If you want to just wait for the worker thread to finish call:
w.join();