解决线程安全问题同步方法和静态同步方法

解决线程安全问题同步方法

解决线程安全问题的一种方案:使用同步代码块格式:

  synchronized(锁对象){

    可能会出现线程安全问题的代码(访问了共享数据的代码)

  }

注意:

  1.通过代码块中的锁对象,可以使用任意的对象

  2.但是必须保证多个线程使用的锁对象是同一个

  3.锁对象作用:

    把同步代码块锁住,只让一个线程在同步代码块中执行

 

 

静态同步方法

Java提供了synchronized关键字用于修饰方法,使用synchronized修饰的方法被称为同步方法。当然,synchronized关键字除了修饰方法之外,还可以修饰普通代码块,使用synchronized修饰的代码块被称为同步代码块。

Java语法规定,任何线程进入同步方法、同步代码块之前,必须先获取同步方法、同步代码块对应的同步监视器。

对于同步代码块而言,程序必须为它显示的指定同步监视器(可为this也可以自定义Object类型的全局变量);对于同步非静态方法而言,该方法的同步

监视器是this----即调用该方法的java对象;对于静态的同步方法而言,该方法的同步监视器不是this而是该类本身。
下面程序提供了一个静态的同步方法及一个同步代码块。同步代码块使用this作为同步监视器,即这两个同步程序单元并没有使用相同的同步监视器,因此它们可以同时并发执行,相互之间不会有任何影响。

上面程序中定义了一个SynchronizedStatic类,该类实现了Runnable接口,因此可作为线程的target来运行.SynchronizedStatic类通过一个staticFlag旗标控制线程使用哪个方法作为线程执行体:
当staticFlag 为真时,程序使用test0()方法作为线程执行体;
当staticFlag 为假时,程序使用test1)方法作为线程执行体。
程序第一次执行SynchronizedStatic对象作为target 的线程时,staticFlag 初始值为true,因此程序将以testo()方法作为线程执行体,而且程序将会把staticFlag修改为false;这使得第二次执行SynchronizedStatic对象作为target 的线程时,程序将以test1()方法作为线程执行体。
程序主方法以SynchronizeciStatic对象作为target启动了2条线程,一条将以testO()方法作为线程执行体,另外一条将以test1()方法作为线程执行体。.

显然是并发执行,并没有达到同步执行(顺序执行)的效果。

静态同步方法可以和以this为同步监视器的同步代码块同时执行,当第一条线程(以test0()方法作为线程执行体的线程)进入同步代码块执行以后,该线程获得了对同步监视器(SynchronizedStatic类)的锁定,第二条线程(以test1()方法作为线程执行体的线程)尝试进入同步代码块执行,进入同步代码块之前,该线程必须获得对this引用(也就是ss变量所引用的对象)的锁定。因为第一条线程锁定的是SynchronizedStatic类,而不是ss变量所引用的对象,所以第二条线程完全可以获得对ss变量所引用的对象的锁定,因此系统可以切换到执行第二条线程

为了更好地证明静态的同步方法的同步监视器是当前类,可以将上面程序中同步代码块的同步监视器改为SynchronizedStatic类。也就是将上面test1()方法定义改为如下形式。

 

 解决线程安全问题的一种方案:使用同步代码块格式:synchronized(锁对象){可能会出现线程安全问题的代码(访问了共享数据的代码)}注意:1.通过代码块中的锁对象,可以使用任意的对象2.但是必须保证多个线程使用的锁对象是同一个3.锁对象作用:把同步代码块锁住,只让一个线程在同步代码块中执行

posted @ 2022-07-08 10:41  肥宅快乐水~  阅读(126)  评论(0)    收藏  举报