在本代码的Info类里面分别定义了一个set同步方法和一个get同步方法 程序从main方法开始运行,然后执行new Thread(pro).start()和new Thread(con).start()以后在同一时间会分别执行Producer类和Consumer类的run()方法 而此时Producer类里的run()方法会调用Info类里面的set()方法,而Consumer类里的run()方法会调用Info类里面的get()方法, (我是这么认为的) 虽然set()方法和get()方法都是同步方法 但是在两个方法执行的过程当中如果在set()方法里执行到this.setName(name)以后此时get()方法开始执行并且没有等到set()方法执行完就已经提前结束 那么会出现content的值为null的现象 可是此代码是不会出现这种情况呢 这是为什么??????!!! class Info{ // 定义信息类
 private String name = "李兴华";  // 定义name属性
 private String content = "JAVA讲师"  ;  // 定义content属性
 public synchronized void set(String name,String content){
  this.setName(name) ; // 设置名称
  try{
   Thread.sleep(300) ;
  }catch(InterruptedException e){
   e.printStackTrace() ;
  }
  this.setContent(content) ; // 设置内容
 }
 public synchronized void get(){
  try{
   Thread.sleep(300) ;
  }catch(InterruptedException e){
   e.printStackTrace() ;
  }
  System.out.println(this.getName() + 
   " --> " + this.getContent()) ;
 }
 public void setName(String name){
  this.name = name ;
 }
 public void setContent(String content){
  this.content = content ;
 }
 public String getName(){
  return this.name ;
 }
 public String getContent(){
  return this.content ;
 }
};
class Producer implements Runnable{ // 通过Runnable实现多线程
 private Info info = null ;  // 保存Info引用
 public Producer(Info info){
  this.info = info ;
 }
 public void run(){
  boolean flag = false ; // 定义标记位
  for(int i=0;i<50;i++){
   if(flag){
    this.info.set("李兴华","JAVA讲师") ; // 设置名称
    flag = false ;
   }else{
    this.info.set("mldn","www.mldnjava.cn") ; // 设置名称
    flag = true ;
   }
  }
 }
};
class Consumer implements Runnable{
 private Info info = null ;
 public Consumer(Info info){
  this.info = info ;
 }
 public void run(){
  for(int i=0;i<50;i++){
   this.info.get() ;
  }
 }
};
public class ThreadCaseDemo02{
 public static void main(String args[]){
  Info info = new Info(); // 实例化Info对象
  Producer pro = new Producer(info) ; // 生产者
  Consumer con = new Consumer(info) ; // 消费者
  new Thread(pro).start() ;
  new Thread(con).start() ;
 }
};

解决方案 »

  1.   

    不知所云,那一句把content设置为null了
      

  2.   

     new Thread(pro).start() ; 
      new Thread(con).start() ; 
    看看线程的执行顺序,是先执行set再执行get,不会出现你说的现象。get永远都能得到值,如果你把上面的反过来写,那么它永远都只能得到一个值“李兴华 --> JAVA讲师”
      

  3.   

    class Productor implements Runnable {
        private TestWaitAndNotify twn;
        
        public Productor(TestWaitAndNotify twn) {
            this.twn = twn;
        }
        
        @Override
        public void run() {
            for(int i=0; i<5; i++) {
                twn.writeCount();
            }
        }
    }class Consumer implements Runnable {
        private TestWaitAndNotify twn;
        public Consumer(TestWaitAndNotify twn) {
            this.twn = twn;
        }
        
        @Override
        public void run() {
            for(int i=0; i<5; i++) {
                twn.readCount();
                
            }
        }
        
    }public class TestWaitAndNotify {
        private int count = 1;
        
        public synchronized void writeCount()  {
            try {
                wait(200); // waiting for consumer
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            
            notify();
            count += 1;
            System.out.println(" -->> Productor: " + count);
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public synchronized void readCount() {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" -->> Consumer: " + count);
            notify();
        }
        
        public static void main(String[] args) {
            final TestWaitAndNotify twn = new TestWaitAndNotify();
            Thread p = new Thread(new Productor(twn));
            Thread c = new Thread(new Consumer(twn));
            p.start();
            c.start();
            
        }}
    console result: -->> Productor: 2 
    -->> Consumer: 2 
    -->> Productor: 3 
    -->> Consumer: 3 
    -->> Productor: 4 
    -->> Consumer: 4 
    -->> Productor: 5 
    -->> Consumer: 5 
    -->> Productor: 6 
    -->> Consumer: 6
      

  4.   

    (我是这么认为的) 虽然set()方法和get()方法都是同步方法 但是在两个方法执行的过程当中如果在set()方法里执行到this.setName(name)以后此时get()方法开始执行并且没有等到set()方法执行完就已经提前结束 那么会出现content的值为null的现象 可是此代码是不会出现这种情况呢 这是为什么??????!!! 因为在set()方法执行没有结束后,get方法不可能有机会得到运行。
    set已经获取了锁但没有释放,get就获取不到锁,就不会执行。

      

  5.   


    我觉得set()方法和get()方法都是由2个不同的线程分别来调用的 所以不存在取锁和释放的概念!!
      

  6.   

    set和get方法都是synchronized的方法,这个是对象级的锁,当一个对象在某个线程中被调用到set或者get方法时,这个对象会被锁住,其余的线程对它的任何操作都必须等待,直到第一个线程执行完毕,释放为止。所以不存在你说的,一个方法执行到一半,另一个线程进入,值为空的情况。
      

  7.   

    set和get方法都是同步方法,它们同步的都是同一个对象,即“this“。当调用同一个实例的这两个方法时,它们会依次运行,不会出现set运行到中间的时候,get开始运行。有一个例外,就是wait方法,调用同一个实例的wait方法时,调用线程会暂时放开同步用的锁,允许其他线程执行。
    给个建议:先看懂书本上的知识,再开始实验。实验是用来加深理解的,不是用来自己猜测的。
      

  8.   

    是这个不?
    http://blog.csdn.net/KingWolfOfSky/archive/2010/04/08/5464990.aspx