您的位置:首页 > 编程语言 > Java开发

JAVA多线程-对象及变量的并发访问(一)synchronized详解

2016-02-20 09:07 519 查看
一、synchronized同步方法

1.1 方法内的变量为线程安全

    非线程安全的问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题,所得结果也就是“线程安全”的了。

1.2 实例变量非线程安全



    如果多个线程共同访问1个对象中的实例变量,则有可能出现“非线程安全”问题。

1.3 多个对象多个锁


    synchronized关键字添加到方法上,取得的锁是对象锁,而不是把一段代码或方法当作锁。如果多个线程访问多个对象,则JVM就会创建多个锁。

1.4 synchronized方法与锁对象


    调用关键字synchronized声明的方法,一定是排队运行的。另外需要牢牢记住“共享”两个字,只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要。
    结论:

(一)A线程先持有Object对象的Lock锁,B线程可以以异步的方式调用Object对象中的非synchronized类型的方法。

(二)A线程先持有Object对象的Lock锁,B线程如果在这时调用Object对象中的synchronized类型的方法则需等待,也就是同步。

1.5 synchronized锁重入

    关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以在得到该对象的锁 的。这也证明在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是可以永远得到锁的。

1.6  出现异常,锁自动释放

1.7  同步不具有继承性

二、synchronized同步语句块

[b]2.1 synchronized的弊端
[/b]

      用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个长时间的任务,那么B线程必须等待比较长时间。这样的情况下可以使用synchronized同步语句块来解决。synchronized方法是对当前对象进行加锁,而synchronized代码块是对某一个对象进行加锁。

2.2  synchronized同步代码块的使用

     当一个线程访问object的一个synchronized同步代码块时,另一个线程仍然可以访问该object对象中的非synchronized同步代码块。

2.3 静态同步synchronized方法与synchronized(class)代码块

(这个比较重要,面试问题中常遇到的问题)

    关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁在static静态方法上直接添加synchronized关键字与局部代码块添加(类名.class)的作用是一致的。

 
   区别:关键字加到static静态方法上是给Class类上锁,而加到非static静态方法上是给对象上锁。

2.4 数据类型的String的常量池特性

    由于常量池具有缓存的功能,所以两个线程中两个锁的锁对象是同一个字符串时,会导致线程同步。也就是一个线程拿到锁,另一个线程堵塞。结论:一般不会使用字符串当作锁对象。

2.5  锁对象的改变

      在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的;如果分别获得锁对象,这些线程之间就是异步的。

    还需要提示一下,只要对象不变,即时对象的属性被改变,运行的结果还是同步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: