`

黑马程序员——多线程间的安全问题

 
阅读更多

                  ------- android培训java培训、期待与您交流! ----------

  • 多线程安全问题

   通过分析发现打印出0-1-2等错票

   多线程的运行出现了安全问题

 问题的原因:

     当多条语句操作同一线程的共享数据时,一个线程只执行了多条语句中的一部分,还没有执行完,就转入冻结状态

   这时另一个线程参与进来,造成对共享数据的破坏

解决办法:

  对操作共享数据的多条语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与!

java对于多线程的安全问题提供了解决方式

1.线程的同步: 就是同步代码块

 synchronized (对象) {

    需要被同步的代码            

  }

2.同步函数:public synchronized void function(){}

     1)同步函数的锁是“this”,

         静态类进入内存时,内存中本没有内存对象,但是,有该类对应的字节码文件对象。

         类名.class  类型是Class

     2)故静态类同步函数的锁是类名.class”,Class类型的对象

  同步代码块运行原理:(同步代码块可以理解为一个有自动开关的容器)

  synchronized (对象)中的对象就相当于一把锁(标志),最开始该锁默认是打开的,

     一旦有一个进程进入该方法体内,该锁便自动关上,只有当该进程将多条处理共享数据的语句

  (期间该进程可能出现冻结状态)都执行完毕后,锁才被自动打开第二个拥有cpu执行权的在进入,继续执行

    这就保证了线程的同步

    

同步的前提:

  1.必须是两个线程或多个线程以上

  2.必须是使用同一把锁

好处:解决了线程的安全问题

弊端:每个线程都需要判断锁,较为消耗资源

如何找安全问题?

  1.哪些代码是多线程运行代码

  2.哪些数据时共享数据

  3.哪些是线程执行过程中,操作共享数据的语句

class Tickt implements Runnable{
      private int tickts=100;
      Object object=new Object();
      public void run(){          
              while(true)
              {   
                  synchronized (object) {
                  if(tickts>0)
                  {   //可能的异常,共三个线程thread-0,thread-1,thread-2
                      //假设tickts=1;thread-0进来,但这时thread-0突然停止运行,thread-1进来,一次类推
                      //就可能导致tickts=0,-1,,-2
                      try {
                          Thread.sleep(10);
                    } catch (Exception e) {
                    } 
                      System.out.println(Thread.currentThread().getName()+"票数:"+tickts--);
                  } 
                  }
              }     

                   

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics