线程不安全的根源就是操作了同一块内存么,共享的数据被多个线程去同时操作读取导致这一块内存中内存不确定就可能导致了一系列问题所以就是就说线程不安全。
为了实现线程安全可以加锁 synchronized
1.synchronized 加在代码块上(synchronized(this))就是这一段代码是同步的,所有被this包起来的代码块会被同步锁上 但是括号外的代码是可访问的,
注意其实产生作用的还是因为锁了(this)实例对象
2.加在方法的定义上就是对整个方法同步 但是snchronized关键字不能继承。
虽然可以使用synchronized来定义方法,但synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized关键字才可以
3.加在对象上 所有有这个对象实例所得地方同步被锁 但是new出来的其他这个对象的实例是不受影响的
A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。 若果想对类实现锁 就得ynchronized(xxx.class) {...}这是因为 JVM中每个类只对应一个Class对象(它是在方法区里边) 锁了Class对象 就相当于锁了类
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制
其实系统中并不存在什么类锁。当一个同步静态方法被调用时,系统获取的其实就是代表该类的类对象的对象锁 在程序中获取类锁 可以尝试用以下方式获取类锁 synchronized (xxx.class) {...} synchronized (Class.forName("xxx")) {...}static :静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。static 实现单例:class Singleton { private Vector v; private boolean inUse; private static Singleton instance = new Singleton(); private Singleton() { v = new Vector(); inUse = true; //... } public static Singleton getInstance() { return instance; } }