1、线程安全与非线程安全的区别?
线程安全:获得的实例变量的值是经过同步处理的,不会出现脏读的现象。
非线程安全:多个线程对同一对象中的实例变量进行并发访问的时候,产生脏读,就是读取到的数据是被更改过的。
* 线程安全的问题存在于实例变量中,如果为方法内部的私有变量,则不会出现非线程安全问题。
2、synchorized关键字加到static方法上是给Class类上锁,加到非static方法上是给对象上锁;
3、volatile与synchorized的区别?
1)、volatile的本质是在告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取,synchorized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2)、volatile只能使用在变量上,synchorized可以使用在变量、方法上。
3)、volatile不会造成线程的阻塞,synchorized可能造成线程的阻塞。
4)、volatile标记的变量不会被编译器优化,synchorized标记的变量可以被编译器优化。
5)、volatile保证数据的可见性(实例变量在多个线程之间的可见性),不能保证原子性,synchorized可以保证原子性,也可以保证可见性,因为它会将私有的内存与公共内存中的数据做同步。
4、wait()、notify()月notifyAll()方法?
wait()的作用是使当前执行代码的线程进行等待,wait()是object类的方法,在调用wait()方法之前,线程必须获得该对象的对象级别锁,即只能在同步方法或者同步块中调用wait()方法,执行wait()方法之后,当前线程释放锁,进入等待队列,直到再次被唤醒。
notify()也是要在同步方法或者同步块 中使用,该方法是用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其他出notify通知,并使他等待获取该对象的对象锁。
notifyAll()方法可以使所有正在等待队列中的同一共享资源的全部线程从等待状态退出,进入可运行状态,此时,优先级最高的那个线程最先执行,但是有可能是随机执行,因为这要取决于JVM虚拟机的实现。
*当执行wait方法后,锁被自动释放,但执行完notify方法后,锁不自动释放,需要等synchorized方法执行完。
*当线程呈wait状态,调用线程的interrupt方法会出现InterruptedException异常
5、什么时候释放锁?
1、执行完同步代码块后会释放对象锁;
2、在执行同步代码块的过程中,如果遇到异常,会释放锁;
3、在执行同步代码块的过程中,执行了锁所属对象的wait()方法, 这个线程会释放锁,而此线程对象会进入线程等待池中,等待被唤醒。