黑马程序员技术交流社区
标题:
多线程同步代码块和同步方法中,锁对象的原理是怎么样的?
[打印本页]
作者:
付鑫鑫
时间:
2013-4-22 20:55
标题:
多线程同步代码块和同步方法中,锁对象的原理是怎么样的?
本帖最后由 付鑫鑫 于 2013-5-13 17:38 编辑
为什么同步代码块的锁对象可以,用任意锁对象.而同步代码块同步方法只能this为锁对象.
作者:
曹睿翔
时间:
2013-4-22 23:53
稍后云版块会推出学习过程中问题以及对知识点的领悟收集!会有技术分奖励,敬请期待、多多参与,要注意按照进度收集问题,那样你会事半功倍。
作者:
王溢君
时间:
2013-4-23 00:43
因为函数前面省略了this.
作者:
Neverbelazy
时间:
2013-4-23 02:22
本帖最后由 Neverbelazy 于 2013-4-23 02:29 编辑
我理解你的问题可以分成下面几个部分解答:
1. Java工程师在设计同步的时候,需要让所可以是任意对象的。
2. 同步方法是一种同步的简写形式,简写就可能付出局限性的代价,
比如下面,这两个是等价的,不过同步方法看起来更简便,但好处似乎又不止这一点,因为一旦定义了synchronized方法,就相当于让外界知到了这个方法是同步的,满足了封装性,又对外提供了方法属性描述
public synchronized void method(){};
//-----------vs-----------------
public void method(){
synchronized(this){
}
}
复制代码
3. 那么,剩下的问题是 为什么不可以这样定义 同步方法;
(这一点我也不知道原因, 不知道是java工程师们有更多的考虑,还是根本没有必要这样定义,
这点还需要请高手解答
)
public synchronized(object) void method(){}
复制代码
4. 最后的问题是,怎么验证同步方法的 锁是 this,毕老师的视频里面给出过一个方法,不过比较复杂,不容易放在帖子上说明,下面提供一段小代码,可以验证同步方法的锁是this
/*
* 1. 造一个带同步函数的线程t1
* 2. 在主函数中加一个同步代码块,同步代码块的锁设定为“调用同步函数”的那个对象(相当于this)
* 现在系统中两个线程:main 和 t1
* 3. 线程内的同步代码为无限循环输出当前线程的名称
* 4. 如果每次输出只是一个线程的名字,即证明两段同步代码公用一把锁,就是说同步方法的锁=2.中传给同步代码块的锁(“调用同步函数”的那个对象)
*/
public class SynchronizedMethodTest {
public static void main(String[] args){
MyThread mt=new MyThread(); //mt对象继承Runnable,课调用run方法传给线程
Thread t1=new Thread(mt); //t1线程传入mt对象
t1.start(); //t1开始,调用run() run调用 synchronized printed (mt=this)
synchronized(mt){ //定义同步代码块:传入mt,此时主线程和t1线程用的同步部分用同一把锁
while(true)
System.out.println(Thread.currentThread());
}
}
}
//定义一个类继承Runnable
class MyThread implements Runnable{
public void run(){
print();
}
public synchronized void print(){ //定义同步方法 要与同步代码块比较
while(true)
System.out.println(Thread.currentThread());
}
}
复制代码
5.补充:静态同步函数的锁是 “类型.class” 对象
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2