public class AchThread extends Thread {
   private  Buffer buf=null;
   
   public AchThread(Buffer buf){
   this.buf=buf;
   }
@Override
      public   void run(){
   buf.put(buf.get()+1);
}

public static void main(String[] args){
Buffer buffer=new Buffer();
Thread[]thread=new Thread[200];
for(int i=0;i<200;i++)
thread[i]=new  AchThread(buffer);
for(int i=0;i<200;i++)
thread[i].start(); try {
sleep(2000);//确保线程运行完
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(buffer.get());


}
} class Buffer {
    public  int i=1;
  
    
    public void put(int i){
     this.i=i;
    }
    
    public int get(){
     return i;
    }
}
Java多线程

解决方案 »

  1.   

    1 代码的目的前提是每个线程累加1, 上述代码线程不安全,Buffer对象被多个线程共享,buf.put(buf.get()+1); 是有问题的,buf.get() 同一时间节点有可能都是拿的同一个value,这样就累加就丢失了。
    改为用AtomicInteger累计就可以了。class Buffer {
        private final AtomicInteger i = new AtomicInteger(1);
    }
    @Override
    public void run() {
        threadIndex.getAndIncrement();
    }
      

  2.   

    public class AchThread extends Thread {
       private  Buffer buf=null;
       
       public AchThread(Buffer buf){
       this.buf=buf;
       }
    @Override
          public   void run(){
       int i=1;
       int in=buf.get();
    //    try {
    // sleep(1);
    // } catch (InterruptedException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
       buf.put(i+in);
    }

    public static void main(String[] args){
    Buffer buffer=new Buffer();
    Thread[]thread=new Thread[100];
    Thread[]thread2=new Thread[100];
    for(int i=0;i<100;i++){
    thread[i]=new  AchThread(buffer);
    thread2[i]=new Down(buffer);
    }
    for(int i=0;i<100;i++){
    thread[i].start();
    thread2[i].start();
    }
    try {
    sleep(2000);//确保线程运行完
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println(buffer.get());


    }
    }class Down extends Thread{
    private  Buffer buf=null;
       
       public Down(Buffer buf){
       this.buf=buf;
       }
    @Override
          public   void run(){
       int i=1;
       int in=buf.get();
    //    try {
    // sleep(1);
    // } catch (InterruptedException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
       buf.put(in-i);
    }
    } class Buffer {
        public  int i=1;
      
        
        public void put(int i){
         this.i=i;
        }
        
        public int get(){
         return i;
        }
    }
    这样一个线程加,一个减,,最终结果是1,,,不安全的不知道怎么变安全了。
      

  3.   

    原因是在线程不是很多的情况下,get set的操作是很快的,虽然原则上不是原子操作,但是由于速度很快,几乎发现不了问题1 手动debug构造条件造成线程不安全,public int get() {
        return i;
    }断点设置在return i;上面,让多个线程return相同的数值后,然后在释放断点让程序 一下执行完毕。2 加大线程数量 到1000,这样理论上有可能会出现这种线程不安全的现象。我这边是出现过
      

  4.   

    我这边加到一万,,结果都一样,,难道我的cpu太给力了...
      

  5.   

    我这里thread 设置为1000,多试几次就有问题了。
      

  6.   

    拆成两步,中间sleep:       public   void run(){
             int temp = buf.get()+1;
                try
                {
                    sleep(10);
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                buf.put(temp);
             }sleep的时间可以调不同值,效果不一样