Java并发编程(03):多线程并发访问,同步控制 (2)

静态方法属于类层级的方法,对象是不可以直接调用的。但是synchronized修饰的静态方法锁定的是这个类的所有对象。

public class AccessVar04 { public static void main(String[] args) { Var04Test var04Test1 = new Var04Test() ; Thread thread1 = new Thread(var04Test1) ; thread1.start(); Var04Test var04Test2 = new Var04Test() ; Thread thread2 = new Thread(var04Test2) ; thread2.start(); } } class Var04Test implements Runnable { private static Integer count ; public Var04Test (){ count = 0 ; } public synchronized static void countAdd() { System.out.println(Thread.currentThread().getName()+";count="+(count++)); } @Override public void run() { countAdd() ; } }

如果不是使用同步控制,从逻辑和感觉上,输出的结果应该如下:

Thread-0;count=0 Thread-1;count=0

加入同步控制之后,实际测试输出结果:

Thread-0;count=0 Thread-1;count=1 6、注意事项

继承中子类覆盖父类方法,synchronized关键字特性不能继承传递,必须显式声明;

构造方法上不能使用synchronized关键字,构造方法中支持同步代码块;

接口中方法,抽象方法也不支持synchronized关键字 ;

三、Volatile关键字 1、基本描述

Java内存模型中,为了提升性能,线程会在自己的工作内存中拷贝要访问的变量的副本。这样就会出现同一个变量在某个时刻,在一个线程的环境中的值可能与另外一个线程环境中的值,出现不一致的情况。

使用volatile修饰成员变量,不能修饰方法,即标识该线程在访问这个变量时需要从共享内存中获取,对该变量的修改,也需要同步刷新到共享内存中,保证了变量对所有线程的可见性。

2、使用案例 class Var05Test { private volatile boolean myFlag = true ; public void setFlag (boolean myFlag){ this.myFlag = myFlag ; } public void method() { while (myFlag){ try { System.out.println(Thread.currentThread().getName()+myFlag); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 3、注意事项

可见性只能确保每次读取的是最新的值,但不支持变量操作的原子性;

volatile并不会阻塞线程方法,但是同步控制会阻塞;

Java同步控制的根本:保证并发下资源的原子性和可见性;

四、源代码地址 GitHub·地址 https://github.com/cicadasmile/java-base-parent GitEE·地址 https://gitee.com/cicadasmile/java-base-parent

Java并发编程(03):多线程并发访问,同步控制

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgzszz.html