java多线程的等待唤醒机制及如何解决同步过程中的安全问题


/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){ 
                 this.sex=sex;
                 this.name=name;  
   }
}
class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           if(x==1){
              p.setPerson("hjz", "man");
           }
           else p.setPerson("哈哈哈", "女女女女");
           x=(x+1)%2;
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           System.out.println(p.name + "....." + p.sex);
       }
   }
}
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}
*/
 
/*
输出的结果:
哈哈哈.....man
hjz.....man
hjz.....man
哈哈哈.....man
hjz.....女女女女
*/
 
//线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){ 
                 this.sex=sex;
                 this.name=name;  
   }
}
 
class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
          synchronized(new Object()){
               if(x==1){
                  p.setPerson("hjz", "man");
               }
               else p.setPerson("哈哈哈", "女女女女");
               x=(x+1)%2;
          }
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           System.out.println(p.name + "....." + p.sex);
       }
   }
}
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}
 */
 
//同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
//本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
/*   class Input implements Runnable{
   int x=0;
   Person p;
    
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
          synchronized(p){
               if(p.flag){
                 try{
                     p.wait();
                   }catch(InterruptedException e){
                   }
               }
               if(!p.flag){
                   if(x==1){
                      p.setPerson("hjz", "man");
                   }
                   else p.setPerson("哈哈哈", "女女女女");
                   x=(x+1)%2;
               }
                
               p.flag=true;
               p.notify();
                
          }
       }
   }
} */
 
 
//现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
//调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){
       synchronized(this){
         if(!flag){
             try{
                wait();
             }catch(InterruptedException e){}
         }
         if(flag){
                 this.sex=sex;
                 try{
                    Thread.sleep(100);
                 }catch(InterruptedException e){}
                 this.name=name;
         }
         flag=false;
         notify();
       }
   }
    
   public void outPerson(){
      synchronized(this){
          if(flag){
             try{
                 wait();
             }catch(InterruptedException e){}
          }
          if(!flag){
              System.out.println(name + "....." + sex);
          }
          flag=true;
          notify();
      }
   }
}
 
class Input implements Runnable{
   int x=0;
   Person p;
    
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
                   if(x==1){
                      p.setPerson("hjz", "man");
                   }
                   else p.setPerson("哈哈哈", "女女女女");
                   x=(x+1)%2;
       }
   }
}
 
class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
           p.outPerson();
       }
   }
} 
 
 
public class Test{
    public static void main(String[] args){
         Person p = new Person();
         new Thread(new Input(p)).start();
         new Thread(new Output(p)).start();
    }
}

上一篇:org.json (json序列化工具)


下一篇:阿里云服务器实例规格怎么选?活动中的实例规格适用场景汇总