一、用关键字synchronized声明方式时,在某些情况下是有弊端的。比如线程A调用同步方法执行一个长时间的任务,那么线程B必须等待很长的时间即A 线程执行完了才可以开始执行,这样是非常耗时的,在这种情况下就可以使用synchronized同步语句块来实现了。
二、synchronized同步代码块的使用
1.synchronized(this)
(1)当两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,一段时间内只有一个线程被执行,另一个线程必须等待当前线程完成这个代码块以后才能执行该代码块,这和synchronized同步方法是一样的。
(2)用同步代码块解决同步方法弊端,即当一个线程访问object的一个synchronized同步代码块时,另一个线程仍然可以访问该object对象中的非synchromized(this)同步代码块。在synchronized块中就是同步执行,不在synchronized块中就是异步执行。
Task.java
public class Task {
public void doLongTimeTask(){
for(int j=0;j<10;j++){
System.out.println("nosyschronized threadName="+Thread.currentThread().getName()+" j= "+j);
}
System.out.println("***********************");
synchronized (this) {
for(int i=0;i<10;i++){
System.out.println("synchronized threadName="+Thread.currentThread().getName()+" i="+i);
}
}
}
}
Thread1.java
public class Thread1 extends Thread{
private Task task;
public Thread1(Task task){
super();
this.task=task;
}
public void run(){
super.run();
task.doLongTimeTask();
}
}
Thread2.java
public class Thread2 extends Thread{
private Task task;
public Thread2(Task task) {
super();
this.task=task;
}
public void run(){
super.run();
task.doLongTimeTask();
}
}
Run.java
public class Run {
public static void main(String[] args){
Task task=new Task();
Thread1 a=new Thread1(task);
a.setName("A");
a.start();
Thread2 b=new Thread2(task);
b.setName("B");
b.start();
}
}
(3)synchronized代码块之间的同步性
当一个线程访问object的synchronized(this)同步代码块时,其他线程对同一个object中所有其他的synchronized(this)同步代码块的访问将被阻塞。
ObjectService.java
public class ObjectService {
public void ServiceMethodA(){
try{
synchronized (this) {
System.out.println("A begin time="+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("A end time="+System.currentTimeMillis());