A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孙汇川 黑马帝   /  2012-2-13 15:10  /  2676 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

老师说同步函数用的锁是this.但this是个对象怎么变成锁了呢?什么是锁?

评分

参与人数 1技术分 +1 收起 理由
admin + 1 不懂就问,好同学

查看全部评分

6 个回复

倒序浏览
同步代码块的格式是:
synchronized(对象)
{
      需要同步的代码;
}
将synchronized写到方法上,就成了同步函数。这时同步代码块上的“synchronized(对象)”括号里面的“对象”就不能自己定义了,但是因为同步函数会被对象调用,但是你不确定对象叫什么名,所以使用到this。

锁的原理:
Java中每个对象都有一个内置锁。当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。

评分

参与人数 1技术分 +2 收起 理由
admin + 2 新人鼓励,多加1分

查看全部评分

回复 使用道具 举报
你说的原理和示例我都知道,但是不明白为什么叫一个对象或者一个类是锁。
回复 使用道具 举报
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享
数据的错误。

解决办法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。
java对于多线程的安全问题提供了专业的解决方式,就是同步代码块或同步函数(均用来封装代码)。
同步代码块:
synchronized(对象)
{
        需要被同步的代码
}

对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取了cpu的执行权,也进不去,因为没有获取到该锁。

同步的前提:
1.必须要有两个或两个以上的线程。
2.必须是多个线程使用同一个锁。

必须保证同步中只有一个线程在运行。

如果你理解了同步代码块中锁的作用,那么同步函数的锁为什么是this你也可以理解的。

多线程同步还可以通过同步函数来实现。

同步函数需要被对象调用,那么函数都有一个所属对象的引用,就是this,所以同步函数使用的锁是this。


如果同步函数被static修饰,使用的锁是该方法所在类的字节码文件对象,即类名.class

评分

参与人数 1技术分 +1 收起 理由
admin + 1 总结得不错

查看全部评分

回复 使用道具 举报
为啥同步?简单来讲,一个线程在对某对象操作时,不想被其他线程的同步方法所干扰。
在实际编程中,我们有两种方式实现同步,分别是同步方法(synchronized methods)或同步块(synchronized block/synchronized statement)。
同步方法是在方法前加synchronized, 如果该方法是static的,则认为锁是相对于Class的,其他线程操作该类的任何对象时,遇到static同步方法或者方法内同步该Class时,需要等待;若该方法不是static的,则认为锁是相对于自身对象(this)的,其他线程操作此对象时,遇到同步方法(非static),需要等待。
同步块一般写在函数里,形式如下:
模式代码  
1.synchronized ( Expression ) Block  
synchronized ( Expression ) Block
Expression需是引用类型(对象,类), Block则是代码块。同步块开始时需要获得Expression的一个互斥锁(mutual-exclusion lock)。当该锁没被其他线程占用时,获取该锁并则执行Block里内容,在Block结束后释放此锁。在执行Block时,任何其他想要获得该锁的线程需要阻塞等待。
[注意点]
1. 可以认为锁是属于引用类型的, 同步的操作需要获取锁之后才进行,否则一直等待。编程时需注意锁(synchronized)的对象
2. 线程在wait后会释放持有的锁。有关wait详细说明参见本文第二部分。
3. 各线程同步时遵守先触发,先得锁原则(happens-before relationship)。
4. 构造函数无法被synchronized。

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
你仔细看看API文档,同步的监视器就是对象监视。所以用this或者建立对象。
回复 使用道具 举报
孙汇川 发表于 2012-2-13 15:58
你说的原理和示例我都知道,但是不明白为什么叫一个对象或者一个类是锁。 ...

这个只是名字问题而已。起名“锁”比较好理解。就像玫瑰花可以不叫玫瑰这个名字,但是还是芳香如故。这个只是我自己的理解。有不同意见者,请多多指教!

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马