先上代码,这是书上的一个代码,有些疑惑:public class SynchronTest implements Runnable {
/**
 * @param args
 */
Book book = new Book();
Object o = new Object();
class  Book {
private String bookname;
public  String getBookname(){
return bookname;
}
public void setBookname(String bookname){
this.bookname = bookname;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SynchronTest sy = new SynchronTest();
Thread t1 = new Thread(sy);
Thread t2 = new Thread(sy);
t1.setName("出版社");
t2.setName("读者");
t1.start();
t2.start();
    }
@Override
public void run() {
// TODO Auto-generated method stub
if(Thread.currentThread().getName().equals("出版社")){
synchronized (o) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
book.setBookname("红楼梦");
System.out.println("出版社出版了一本"+ book.getBookname());
}
}
if(Thread.currentThread().getName().equals("读者")){
synchronized (o) {
System.out.println("读者购买了一本"+ book.getBookname());
}
    }
    }
}
输出结果是: 出版社出版了一本红楼梦
                         读者购买了一本红楼梦因为出版社线程和读者线程都需要访问BOOK类中的数据,所以涉及到线程安全问题,就用到了
synchroniized  这个同步锁,我的疑问是:
 在两个线程调用了   .start()  之后 ,从新建状态切换到就绪状态,然后等待CPU的调用,这个时候如果cpu 先调用了读者线程,那么  输出应该是 
 读者购买了一本null
出版社出版了一本红楼梦我想知道为什么输出结果里不会出现这种情况呢?    只有将t2.start(); (读者线程)写在t1.start() (出版社线程)之前才会有这样的结果, 可是我记得CPU调用的时候是CPU自己决定的,跟这个顺序没有关系吧    求细致解答javathread同步     synchronized 

解决方案 »

  1.   

    的确t1和t2两个线程start后,CPU先调度谁不是我们说了算的。我们可以猜测,在时间上是t1先启动的,CPU可以更倾向于让t1比t2先开始执行。当然这只是猜测,我们无法保证CPU每次都这样做。为了保险起见,我们要在代码中加以限制,使“出版社”没有出版这本书之前,不允许“读者”去购买它。
    楼主应该使用wait()和notify()来完成这一目标,而不是采用让t1线程休眠1秒的方式,因为这依然无法保证出版书和购买书的先后顺序。可以挂载调试器做个实验,
    这种情况是完全可以出现的。
      

  2.   

    使用wait()和notify()来完成比较好