线程安全,主要存在于多个线程访问同一个对象中的实例变量所导致的数据不同步的问题,要是在方法内部才使用到的局部变量,是不会导致线程安全的
使用synchronized关键字锁住的是实例对象,要是synchronized关键字修饰的是方法名,那么多个线程只有访问相同的方法时才需要等待锁的释放,也就是说其他线程可以访问没有用synchronized修饰的方法
synchronized锁的重入
也就是说一个线程在获得进入某个被锁了的方法的时候,再次请求改对象锁时,是可以直接拿到的,也就是说可以直接进入该类的其他被锁了的方法,如:
public class TestObject{
synchronized public void service1(){
System.out.println("start service1");
service2();
}
synchronized public void service2(){
System.out.println("start service2");
}
}
我们还可以使用synchronized来同步代码块来获取高效的执行时间,也就是只有在设置公共的实例变量的代码部分才使用synchronized来锁定,类似同步方法,同步代码块也是锁定对象的如:
public void test(a, b){
synchronized(this){
this.a = a;
this.b = b;
}
}
public void getTest(){
synchronized(this){
System.out.println("a=="+a+"b="+b);
}
}
同样我们的synchronized也可以锁定一个任意的对象,而不一定是this对象,这样只有锁定同一个对象的锁,才会出现同步运行的线程效果,要是锁的对象不一样,那么就会异步运行
对于方法的锁,要是两个线程先后访问不一样的方法,可能会导致数据的不同步,这个情况下,最好就是使用一个单例作为锁的对象,这样就能保证在一个线程执行完之后,下一个线程才进来执行
synchronized(x)是锁住x对象,所以x对象里面的同步方法和synchronized(this)的代码块都会被锁住,也就是都会同步执行