8-线程安全问题_多线程中的共享变量

出问题了,共享变量

我们先来看一段代码

public class Main {
    public static void main(String[] args) throws InterruptedException {
       TheThread theThread1=new TheThread();
        TheThread theThread2=new TheThread();
        theThread1.start();
        theThread2.start();
    }
    static int  i = 0;
    public static class TheThread extends Thread{
        public void run(){
           for(;i<100;){
                i++;
                System.out.println(Thread.currentThread().getId()+":"+i);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

这个运行的最终结果本来应该是200,但是结果远远小于200,如果循环次数越多,则结果差距越大,这是为什么呢?

当一个线程区访问这个变量的时候,另外的线程也可以访问,在修改值得时候,存在同时修改的可能性,这时候i只能被赋值一次,这就导致了一个问题。这个问题我们叫做线程安全问题。这个变量我们称作共享变量。

解决问题:同步

并发中,共享变量会导致的一个问题就是线程安全问题,为了解决这个问题,我们要做的就是控制线程访问。在一个线程在访问的这个共享资源的时候,其他线程无法访问,这就是同步。

Java为了解决同步问题,专门设置了关键字,叫synchronized,我们来写一个线程安全的代码:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        int i=0;
        ObjA o=new ObjA(i);
        TheThread theThread1=new TheThread(o);
        TheThread theThread2=new TheThread(o);
        theThread1.start();
        theThread2.start(); 
    }
}
class TheThread extends Thread { 
      private ObjA objA;
      public TheThread(ObjA objA) {
          this.objA=objA;
      } 
      public void run() { 
          objA.method(); 
      }
 }

class ObjA{
      int i;
      public ObjA(int i) { 
          this.i=i; 
      }
      synchronized public void method() {
            for(int j=0;j<50;j++) {
                i++;
                System.out.println(i);
        }
    }
}

你可能感兴趣的:(8-线程安全问题_多线程中的共享变量)