下面三种使用synchronized的方式。
麻烦各位大神说说他们的不同之处。A:
public void synchronized methodA(){
//......
}
B:
private int i = 0;
public void methodB(){
synchronized(i){
//..........
}
}
C:
public void methodC(){
synchronized(this){
//..........
}
}synchronized同步块和同步对象synchronized的使用怎么使用synchronized
麻烦各位大神说说他们的不同之处。A:
public void synchronized methodA(){
//......
}
B:
private int i = 0;
public void methodB(){
synchronized(i){
//..........
}
}
C:
public void methodC(){
synchronized(this){
//..........
}
}synchronized同步块和同步对象synchronized的使用怎么使用synchronized
A写法是阻止多线程同时执行该方法
B写法是使用对象锁,锁定对象i,在多线程访问该方法的时候,判断i是否被锁定,如果被锁定就要进入等待池等待i的锁被释放,然后优先级最高的进程或者这个锁,继续执行下面的方法
B写法应该是锁定这个类这是我的理解,不知道有没有什么问题,求各位大神拍砖
B锁的是变量i
1. synchronized是JAVA5之前同步的必需品,即给方法或者代码块加锁,既然加锁,就得有锁对象,这样大家进来的时候才知道:哦,咱们用的是同一把锁,既然你锁上了,那么我就只能等待;2. synchronized默认的锁对象是this,因此A情况的锁对象是this,和C情况的锁对象一致;不过A情况的锁作用的范围是整个方法,C情况的锁作用的范围是其后面的大括弧括起来的代码块。3. B情况是写明锁对象为i,不过i应该声明为private Integer i = 0; 不然eclipse不通过。4. 如果两个线程同时读到同一个锁对象的代码,则其中一个肯定得等待另一个完成后才能进入;注意,默认情况下的this,如果是new了两个对象,然后分别让两个线程调用,则这两个this是不一样的,也就是不会出现等待的情况。
public synchronized void methodA(){
....
}
B.编译出错,应该为
private Integer i = 0;
public void methodB(){
synchronized(i){
}
}
C 编译正确
A功能上等效于C,为初始化对象时,自动产生对象锁。
执行B方法是,一次只能有一个线程进入。
谢谢纠正代码。。
可以这么理解?
A与C 在初始化对象时,就产生了这个对象的锁,所以这个对象的所有方法和属性(包括静态方法和属性)都不可以被其他线程调用?
B方法表明:只是这个方法被锁定了,这个类的其他方法和属性都可以被其他线程方法?有一个问题。。
假设 A方法对于的类是ClassA
现在我声明2个变量。
ClassA cls1 = new ClassA();
ClassA cls2 = new ClassA();
线程1中:cls1.methodA();
线程2中:cls2.methodA();// 这里会不会已经被cls1锁定了,而进入等待状态?
当一个线程进入一个对象的一个 synchronized 方法后,其它线程只能访问该对象的其它非同步方法,同步方法则不能进入。对于上面这句话举个很简单的例子:有一个院子:里面有很多门,一些门是锁着的,另外一些门是开着的,但是 锁着的门 只有一把钥匙,这个钥匙能够开所有院子中锁着的门, 院子代表了一个对象,门代表了很多加锁同步的方法。我说一下A 和C 的区别:
public void synchronized methodA(){
//......
}一旦进入调用对象的方法,对象就会加锁,下面就会出现一个问题,如果该加锁方法中调用了一个另外的加锁方法会出现什么问题呢? 这个加锁方法没有执行完,不会释放对象锁,在该方法中调用的加锁方法因为得不到相应的对象锁所以也无法调用就会出现死锁现象。
为了解决这个问题 就出现了Cpublic void methodC(){
synchronized(this){
//..........
}
}对方法中需要加锁的部分进行加锁,其他部分可以调用其他加锁的方法,这样能够解决以上疑问:
下面是个很好的例子:public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
addName中 需要对修改 lastName 和 nameCount的值加锁,但是还需要调用加锁的方法add 为了避免死锁,把lastName 和 nameCount的修改部分加锁, 后面再调用加锁的add 方法 就没有问题了。这是我的理解。 欢迎拍砖。