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

多线程编程核心技术读书笔记(二):对象及变量的并发访问(synchronized关键字)

2017-09-01 11:49 796 查看
“非线程安全”问题存在于“实例变量”中,如果是方法内的私有变量,则不存在“非线程安全”问题;

即:方法内的变量为线程安全。

实例变量为非线程安全,(因为为公用资源)

关键字synchronized取得的锁,都是对象锁,而不是对一段代码或者函数当做锁,也就是synchronized锁住的是对象;如果多线程访问的是多个对象,那JVM会创建多个锁;

共享资源的读写访问才需要同步化;

**问题:当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法?

1. 其他方法前是否加了 synchronized 关键字,如果没加,则能。

2. 如果这个方法内部调用了 wait,则可以进入其他 synchronized 方法。

3. 如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait,则不能。

4. 如果其他方法是 static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是 this。**

锁重入:synchronized拥有锁重入功能,即现在拥有当前锁,此时还想调用这个对象的另外的synchronize方法,是可以的,如果不可以,就会死锁;继承关系中,子类可以调用父类的同步方法;

当出现异常时,锁将自动释放;

同步不可以继承:重写函数也要加synchronized关键字

synchronized同步语句块

1、当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

2、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

3、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

其实synchronized代码块也是获得的“对象”锁,

synchronized方法是对当前对象进行加锁,synchronized代码块是对一个对象进行加锁(synchronized(this)就是锁住当前对象;synchronized(非this对象)就是锁住这个非this对象,可以是任意对象,比如实例变量或者方法参数;synchronized(class)锁住的是这个class对象,影响class的一切实例;synchronized(static XXX)锁住的是当前类对象,因为static对象是所有类实例共有的资源;括号中的就是对象监视器,只有获取这个对象监视器才可以执行相应代码)

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

Synchronized加到static静态方法上就是对class类上锁,影响所有该class创建的实例对这个class类中所有静态方法的调用,实现同步;不影响其实例对象对非静态方法的调用;class锁,可以对类的所有实例起作用(对static资源的调用);synchronized(class)代码块的作用和这个一样,锁住class这个类;**

数据类型String的常量池特性:在程序中str1 = “string”,与str2 = “string”实际是指向一个对象,所以在应用锁的时候synchronized(str1)与synchronized(str2)请求的是同一个锁。因此在大多数情况下,同步synchronized代码块都不使用String作为锁对象。改用其他的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: