非线程安全
其实会在多个线程对同一个对象中的实例变量进行并发访问时产生。产生的后果就脏读
,也就是得到的数据是被修改过的。而线程安全
就是以获得的实例变量的值是经过同步处理过的,不会出现脏读的现象。
非线程安全
问题存在于实例变量
中,如果是方法内部的私有变量,则不存在非线程安全
问题,这是方法内部的变量是私有的特性造成的。
【注意】:关键字
synchronized
取得的锁都是对象锁,而不是把一段代码或方法当作锁。哪个线程先执行带synchronized
关键字的方法,哪个线程就持有该方法所属对象的锁Lock,那么其他线程只能呈等待状态 【前提是多个线程访问的事同一个对象!!!】
synchronized
方法与锁对象:
public class ThreadA extends Thread {
private MyObject object;
public ThreadA(MyObject object){
super();
this.object = object;
}
@Override
public void run() {
super.run();
object.methodA();
}
}
public class ThreadB extends Thread{
private MyObject object;
public ThreadB(MyObject object){
super();
this.object = object;
}
@Override
public void run() {
super.run();
object.methodA();
}
}
public class Run {
public static void main(String[] args) {
MyObject object = new MyObject();
ThreadA a = new ThreadA(object);
a.setName("A");
ThreadB b = new ThreadB(object);
b.setName("B");
a.start();
b.start();
}
}
public class MyObject {
public void methodA(){
try {
System.out.println("begin methodA threadName="+Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果1:
在methodA方法前加上synchronized可得到运行结果2
synchronized public void methodA()
锁重入:
在使用sychronized关键字时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁。
可重入锁的概念是:自己可以再次获取自己的内部锁
当存在父子类继承关系时,子类完全可以通过“可重入锁”调用父类的同步方法。