上篇博客说了同步方法,这篇博客我们来看一下同步语句块的相关内容。首先,一起学习一下基础知识。
1、使用synchronized关键字声明方法,从运行时间上看,弊端明显
2、当一个线程访问object的一个synchronized同步代码块时,另一个线程仍然可以访问该object对象中的非synchronized(this)同步代码块,所以仅将可能发生问题的代码块放即可
3、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的对象监视器是一个
4、synchronized关键字加到static静态方法上是给class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁。
5、同步synchronized代码块都不使用string作为锁对象,而改用其他,如果new object实例化一个对象,但并不放入缓存中
6、只要互相等待对方释放锁就有可能出现死锁
通过一个简单的小例子,我们来体会一下
DealThread类:
publicclassDealThreadimplementsRunnable{
publicStringusername;
publicObjectlock1=newObject();
publicObjectlock2=newObject();
publicvoidsetFlag(Stringusername){
this.username=username;
}
@Override
publicvoidrun(){
if(username.equals("a")){
synchronized(lock1){
try{
System.out.println("username="+username);
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
synchronized(lock2){
System.out.println("按Lock1->lock2代码顺序执行了");
}
}
}
if(username.equals("b")){
synchronized(lock2){
try{
System.out.println("username="+username);
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
synchronized(lock1){
System.out.println("按Lock2->lock1代码顺序执行了");
}
}
}
}
}
Run类:
publicclassRun{
publicstaticvoidmain(String[]args){
try{
DealThreadt1=newDealThread();
t1.setFlag("a");
Threadthread1=newThread(t1);
thread1.start();
Thread.sleep(100);
t1.setFlag("b");
Threadthread2=newThread(t1);
thread2.start();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}