Java synchronized 关于…
2015-09-10 16:32
561 查看
关于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){
};[/b]
[/b]
public static void
main(String [ ] args){[/b]
TT tt =new TT ();
tt.start();
tt.method B(int a);
}// 因为方法A和方法B锁定的是同一对象中的方法 为[/b]synchronized
锁定的是对象而不是方法 那么当方法b先获得锁之后
那么a就发生阻塞 必须等到方法b执行完毕之后在去执行方法a 因为方法b为主线程的调用
会比开启新线程得到锁的速度要快
所以要根据情况设定SLEEP的时候来确定需要的线程先得到锁[/b]
附一下代码
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
相关文章推荐
- java 线程synchronized 线程同步
- Java Swing 中插入图片背景
- java.io.Console的使用以及重定向…
- http://java.sun.com/jstl/core cannot be resolved
- spring mvc+hibernate 实现事务管理(全注解版)
- lombok 简化java代码注解 理解
- java蓝图
- Spring声明式事务
- Java虚拟机内存区域---学习笔记
- Java虚拟机内存区域---学习笔记
- Java 反射概述
- 使用WebSocket实现网页聊天室
- Spring-Aop
- Spring静态工厂和扫描器
- Spring MVC
- Struts2 实战(一)
- Spring-IOC
- scope的取值对spring容器创建对象的单/多例的影响
- Java web过滤器验证登录(避免未经登录进入主页)
- java动态代理(JDK和cglib)