误区一:synchronized关键字只能用在实现Runnable或者继承了Thread类的子类的方法里面。
正解:如果有一块代码(或方法)可能被多个线程同时访问,然后里面操作的数据修改操作可能因为不同线程的操作而不一致的时候,使用synchronized锁定这块代码,确保同时只有一个线程访问这个代码块。也就是说,关键字synchronized可以用在任何类的方法里面,即使该类没有实现Runnable接口或者继承Thread类。
误区二:synchronized(this)和synchronized(object)作用范围完全不同。
正解:当多个线程访问同一个类 A 的方法 A() 的时候。并且,这个方法 A() ,要求一个线程执行完了之后再给另外一个线程去执行。那么,这个方法 A() 就必须加上 synchronized 关键字,或者,在该方法 A() 中写上
synchronized(this//指代当前类A的实例) { }
如果不在声明方法 A() 时,加上 synchronized 关键字,或者,不在方法 A() 中加上 synchronized(this){ }
同步块的时候可以在线程类的 run() 方法内
synchronized(Object //指代类A的实例){
Object.A();
}
实现多线程同时有序访问该同步块内类 A 的方法 A() 的目的。
object本身就包含this的情况。
this 指代的是当前同步块所在方法所在的类,当不需要引用别的类的时候。
object 指代的是需要调用的类,引用了别的类,且需要处理多线程并发访问时,object 指代的是被引用的类。如果没有引用别的类,则指代的就是同步块所在方法所在的类本身。
例:
public class 访问类 {
public void A方法() {
//synchronized (this) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " i = "
+ i);
}
//}
}
public void B方法() {
//synchronized (this) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " i = "
+ i);
}
//}
}
}
public class 实例线程类 {
public static void main(String[] args) {
访问类 Object = new 访问类();
Thread t1 = new Thread(new 线程A(Object));
Thread t2 = new Thread(new 线程B(Object));
t1.start();
t2.start();
}
}
class 线程A implements Runnable {
private 访问类 object;
public 线程A(访问类 object) {
// TODO Auto-generated constructor stub
this.object = object;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (object) {
object.A方法();
}
}
}
class 线程B implements Runnable {
private 访问类 object;
public 线程B(访问类 object) {
// TODO Auto-generated constructor stub
this.object = object;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (object) {
object.B方法();
}
}
}