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

Java synchronized 关于锁的对象顺序问题

2015-05-29 22:16 513 查看
关于synchronized 这东西就是看对象 目前也是很木乱 还是要多敲 自己REBUG 坑总是会填满的

—————–我是分割的小尾巴 啦啦啦啦

下列是方法

public synchronized void methodA(int a, int b);

public synchronized void methodB(int a){

methodA(a, 0);

}

那么对于顺序问题怎么看呢

要明白两个问题,1.锁的对象是谁,2.谁持有了锁。

假设方法A和B是在同一个类Test中的两个方法。

Test t=new Test();

t.methodB();

这个时候,methodB方法被调用时,因为加了synchronized ,需要先获得一个锁,这个锁的对象应该是t,也就是当前的这个Test类的实例,而获得锁的东西是线程,也就是说当前线程拿到了t的锁(而不是你说的B方法获得锁),这个时候B方法内调用methodA,因为A也加了synchronized,也需要获得一个锁,因为A和B都是Test类中的方法,所以当前线程要获得的锁的对象也是t。由于当前线程在执行B方法时已经持有了t对象的锁,因此这时候调用methodA是没有任何影响的,相当于方法A上没有加synchronized。

另一种情况:假设现在有两个Test类

Test t1=new Test();

Test t2=new Test();

t1.methodB();//此时当前线程持有了t1对象的锁

t2.methodB();//此时当前线程也持有了t2对象的锁

当前线程持有了两把锁,锁的对象分别是两个不同的Test类的实例t1和t2,互相没有影响。

再一种情况:假设在多线程环境下,两个线程都可以访问Test t=new Test();

此时假设thread1里调用t.methodB();同时thread2里调用t.methodB()

这时假设thread1先抢到t对象的锁,那么thread2需要等待thread1释放t对象的锁才可以执行B方法。

结果像这样:

thread1获得t的锁–thread1执行methodB–thread1执行methodA–释放t的锁—thread2获得t的锁–thread2执行methodB–thread2执行methodA–释放t的锁。

写在后面

如果是下面这个样子

public synchronized void methodA(int a, int b);

public synchronized void methodB(int a){

};

public static void main(String [ ] args){

TT tt =new TT ();

tt.start();

tt.method B(int a);

}// 因为方法A和方法B锁定的是同一对象中的方法 为synchronized 锁定的是对象而不是方法 那么当方法b先获得锁之后 那么a就发生阻塞 必须等到方法b执行完毕之后在去执行方法a 因为方法b为主线程的调用 会比开启新线程得到锁的速度要快 所以要根据情况设定SLEEP的时候来确定需要的线程先得到锁

附一下代码

package n1;

public class test11 implements Runnable{
int b =100;
public synchronized void A() throws InterruptedException{
System.out.println(Thread.currentThread().getName()+":"+"B值修改为1000");

b=1000;

System.out.println(Thread.currentThread().getName()+":"+"运行方法A");

Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+":"+"A" +b);
}
public synchronized void B() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+":"+"运行方法b");
Thread.sleep(2500);
b=2000;

System.out.println(Thread.currentThread().getName()+":"+"B" +b);

}
public void run() {
try {
A();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
test11 t =new test11();
Thread i = new Thread(t);
i.start();     t.B();
System.out.println(Thread.currentThread().getName()+":"+"运行方法main"+t.b);

}
}


结果:

main:运行方法b

main:B2000

Thread-0:B值修改为1000

Thread-0:运行方法A

main:运行方法main1000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  synchronized