文章目录
-
- synchronized同步代码块处理线程安全
- synchronized同步方法处理线程安全
- lock锁处理线程安全
- 优先级:lock > 同步代码块 > 同步方法
synchronized 和 lock锁处理线程安全
synchronized同步代码块处理线程安全
class TEST implements Runnable{
//这个时候TEST类多new一次,obj就多一个,每个对象的obj都是新new的,锁都不一样private Object obj = new Object();@Overridepublic void run() {
//Thread test1=new TEST();Thread test2=new TEST();//如果2个线程都用test1,那么这里的obj就是一样了,锁要抢的//如果2个线程一个是test1,一个是test2,那么你的obj是你new的,他的obj是他new的,你能锁住他?//年轻人要将武德,你家门上了锁,锁的你家的门,你还不让我回自己家?我家的锁是我的又不是你的synchronized(obj){
//需要被同步的代码,需要执行的操作写在这,需要的包起来,包多了影响效率,且可能会出错//操作}}}class TEST2 extends Thread{
//现在obj变成静态的了,不管new几次TEST2,obj都只有一个了,锁也是一把了//这把锁就牛b了,我们都在一个小区,你把小区锁了,几百户人都进不去private static Object obj = new Object();@Overridepublic void run() {
//这时候不管test1,还是test2,两个线程//一个从东走,一个从南走,最后还是汇合到了一个岔路口,obj是一样的,谁抢到obj谁先过synchronized (obj){
}}
}
synchronized同步方法处理线程安全
class TEST3 implements Runnable{
@Overridepublic void run() {
//需要同步的操作单独用方法包起来test();}public synchronized void test(){
//非静态的:同步监视器默认的是this,this是指类的对象,实例对象可以new多个//如果new了2个TEST3,假设为test1和test2,Thread test1=new TEST3();Thread test2=new TEST3();//就存在2个对象//test1和test2走的是不同的路线,是不可能出现同步的,虽然代码是一样的,但是开辟的是2条路,各走各的//但是如果开启了2个test1,如Thread threa1=new Thread(test1);Thread threa2=new Thread(test1);///有两个线程都使用了test1对象,那么两个线程就会争夺锁,这时候的锁就是对象test1,大家都是test1的锁,谁抢到就是谁的,抢不到就等着}
}
class TEST4 extends Thread{
private static Object object = new Object();@Overridepublic void run() {
test();}public static synchronized void test(){
//静态的:同步监视器不是this,是TEST4.class,当前类//不管你new多少个TEST4,反正都是TEST4类的,锁都是TEST4类的锁//不管你是test1还是test2,虽然路走的不同,但是奈何有个岔路口我们重合了,大家都要抢着过}
}
lock锁处理线程安全
lock是一个接口,使用lock接口要使用实现类ReentrantLock
/*** lock接口,实现类ReentrantLock* 锁lock.lock();* 解锁lock.unlock();* lock是手动启动同步,手动结束同步* synchronaized是执行完成代码以后自动释放的*/
class Test2 implements Runnable{
//实现类,如果是继承类lock要是静态的,使用同一个锁private ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {
try{
//手动调用lock锁上lock.lock();}finally {
//手动调用解锁lock.unlock();}}
}