在spring的源码中,看到了关于synchronized的关键字的语句,但是对多线程的概念理解不是很清晰,所以想询问下高手。
protected final void refreshBeanFactory() throws BeansException {
// Shut down previous bean factory, if any.
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory != null) {
this.beanFactory.destroySingletons();
this.beanFactory = null;
}
}
....................
............
}这是spring中的一段代码,比较混乱的是synchronized后括号中的对象,在多线程中有很多定义同步的实现方法,来解决数据的安全性,我知道如果后面跟的是this,那应该是调用这个方法的对象的值。那么如果写明一个object的类型的对象作为参数,应该是什么意思呢,(this.beanFactoryMonitor)
看了解释,似乎应该是这个对象作为锁,如果哪个线程得到了这个对象的锁,就可以执行下面的代码块,那么不明白的是,怎么样判断哪个线程可以得到这个对象的锁呢,这个参数比较不理解,请高手帮解释下,谢谢
ps:如果上面有说的错误的,请帮忙更正,谢谢
protected final void refreshBeanFactory() throws BeansException {
// Shut down previous bean factory, if any.
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory != null) {
this.beanFactory.destroySingletons();
this.beanFactory = null;
}
}
....................
............
}这是spring中的一段代码,比较混乱的是synchronized后括号中的对象,在多线程中有很多定义同步的实现方法,来解决数据的安全性,我知道如果后面跟的是this,那应该是调用这个方法的对象的值。那么如果写明一个object的类型的对象作为参数,应该是什么意思呢,(this.beanFactoryMonitor)
看了解释,似乎应该是这个对象作为锁,如果哪个线程得到了这个对象的锁,就可以执行下面的代码块,那么不明白的是,怎么样判断哪个线程可以得到这个对象的锁呢,这个参数比较不理解,请高手帮解释下,谢谢
ps:如果上面有说的错误的,请帮忙更正,谢谢
好比桌子上有一个金牌现在有一件事情,比如做饭,只有手持这块金牌的人才能做我先把金牌拿走了,我有权利做饭此时你也想做饭,你也去拿那块金牌,但是还在我手上,你只得等我把金牌放回来,也就是退出了ynchronized (this.beanFactoryMonitor) 块
Java多线程编程总结
实现了对对象状态的互斥访问
建立了对可见性至关重要的happens-before关系每一个对象都有一个内部锁,beanFactoryMonitor不会例外,传统上,线程如果想要实现对对象域互斥且一致的访问就需要在访问对象域前去获得对象的内部锁,在访问结束后又释放内部锁。线程在获得锁和释放锁之间的时间里被称作拥有了内部锁。只要线程拥有着内部锁,其它线程就无法再拥有同一个锁,其它线程在想要尝试获得该锁时会阻塞。当一个线程释放内部锁时,在释放动作与任何接下来的获得同一个锁的动作之间一个happens-before关系就会被建立。保证先于获得而释放,同时又建功于可见性。
sychonized()里面的对象就是加锁的对象,如果它是this,那就是调用本方法的对象,如果是this.beanFactoryMonitor),那就是调用本方法的对象(this)的成员变量beanFactoryMonitor,它也是一个对象。这个语句的功能只是说明,从现在以后,任何一个线程想要执行sychonized块中的语句,必须先申请beanFactoryMonitor对象上的锁,如果别的线程已经得到了锁,那它就不可能执行sychonized块中的语句了。至于哪个线程先获得这个锁,那要看程序的执行过程了,仅仅从你上面贴的这段代码中是看不出来的。
int num = 200; public void count_num() {
this.num--;
} public static void main(String args[]) {
Count c = new Count();
ThreadNum t1 = new ThreadNum(c);
ThreadNum t2 = new ThreadNum(c);
ThreadNum t3 = new ThreadNum(c);
ThreadNum t4 = new ThreadNum(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}class ThreadNum extends Thread {
Count t_;
String name; public ThreadNum(Count t) {
this.t_ = t;
} public void run() {
while (true) {
synchronized (t_) {
this.name = Thread.currentThread().getName();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(t_.num > 0){
t_.count_num();
}else{
break;
}
System.out.println(this.name + " " + t_.num);
}
}
}
}顺便给楼主一个自己的例子吧
是的,可以任意取名,也可以不是 Object 对象,弄个 String lockMonitor = ""; 之类也是可以的,因为每一个对象都有一个监视器。
这把钥匙能够开启所有使用该钥匙锁起来的代码块
但是该钥匙同时只能被一个线程拥有.所有的对象,都可以当成锁。常见的this及XXX.class或者任意一个对象,都可以拿来当钥匙
我只想知道这个答案,那如果真的是这样的话,那不如直接用this了,还有必要在该类中定义一个实例化对象作为参数么,这样有什么意义?