I am making Bean as a singleton class, where i have setter and getter for bean.ThreadA and ThreadB using the singleton object of Bean. I want ThreadA should perform its task first and then ThreadB should start its execution. I am getting inconsistent . I have my doubts whether my code is improper or how can i make my code completely thread safe. Hoping for the cooperation.
public class Test {
public static void main(String args[])
{
Bean bean = Bean.getInstance();
new ThreadA(bean);
new ThreadB(bean);
}
}
class Bean
{
private static Bean instance = null;
protected Bean() {
// TODO Auto-generated constructor stub
}
int x;
public static Bean getInstance()
{
if(instance==null)
{
instance=new Bean();
synchronized (instance) {
instance=new Bean();
}
}
return instance;
}
public synchronized int getX() {
return x;
}
public synchronized void setX(int x) {
this.x = x;
}
}
class ThreadA extends Thread
{
Bean b;
public ThreadA(Bean b) {
this.start();
this.b=b;
}
@Override
public void run() {
for (int i=1;i<=10;i++)
{
this.b.setX(i);
System.out.println(Thread.currentThread().getName() + " "+this.b.getX());
}
}
}
class ThreadB extends Thread
{
Bean b;
public ThreadB(Bean b) {
this.start();
this.b=b;
}
@Override
public void run() {
for (int i=1;i<=10;i++)
{
this.b.setX(i);
System.out.println(Thread.currentThread().getName() +" "+ this.b.getX());
}
}
}
Thread-0 1 Thread-0 2 Thread-0 3 Thread-0 4 Thread-0 5 Thread-0 6 Thread-1 1 Thread-0 7 Thread-1 2 Thread-1 3 Thread-1 4 Thread-1 5 Thread-0 8 Thread-1 6 Thread-1 7 Thread-1 8 Thread-1 9 Thread-1 10 Thread-0 9 Thread-0 10
I am getting inconsistent result like above . I want My Thread-0 which is ThreadA should perform the task first and then ThreadB = Thread-1 should start it's execution.
/////////////////////////////my changed code starts below
package p1;
public class T {
public static void main(String args[])
{
Bean1 bean = Bean1.getBean1();
new ThreadA(bean);
// bean.lock(true);
new ThreadB(bean);
}
}
class Bean1
{
private static Bean1 instance = null;
static boolean threadAFinished=false;
private Bean1() {
}
private boolean beanLocked;
synchronized public void lock (boolean b) {
if(b)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
beanLocked=b;
}
synchronized public boolean getLock()
{
if(!beanLocked)
{
notify();
}
return beanLocked;
}
int x;
public static Bean1 getBean1() {
if (instance==null) {
instance=new Bean1();
}
return instance;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
class ThreadA implements Runnable {
Bean1 b;
public ThreadA(Bean1 b) {
this.b=b;
new Thread (this).start(); // run() uses b, set it before starting the thread
}
@Override
public void run() {
for (int i=1;i<=10;i++) {
b.setX(i);
System.out.println(Thread.currentThread().getName() + " "+b.getX());
}
b.threadAFinished=true;
b.lock(false);
b.getLock();
}
}
class ThreadB implements Runnable {
Bean1 b;
public ThreadB(Bean1 b) {
this.b=b;
new Thread(this).start();
}
@Override
public void run() {
if(!b.threadAFinished)
{
b.lock(true);
}
for (int i=1;i<=10;i++) {
b.setX(i);
System.out.println(Thread.currentThread().getName() +" "+ b.getX());
}
}
}