我将 Bean 制作为单例类,其中我使用 Bean 的单例对象为 bean.ThreadA 和 ThreadB 设置了 setter 和 getter。我希望 ThreadA 应该首先执行它的任务,然后 ThreadB 应该开始它的执行。我越来越不一致。我怀疑我的代码是否不正确,或者如何使我的代码完全线程安全。期待合作。
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 线程 1 6 线程 1 7 线程 1 8 线程 1 9 线程 1 10 线程 0 9 线程 0 10
我得到的结果与上面的不一致。我希望我的 Thread-0 是 ThreadA 应该首先执行任务,然后 ThreadB = Thread-1 应该开始它的执行。
/////////////////////////我更改的代码从下面开始
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());
}
}
}