java-线程同步

线程世界出现了一把锁

幸好还是又聪明人的,有人想到了一个解决问题的好方法。虽然不知道谁想到的注意,但是这个注意确实解决了一部分问题,解决的方案是加锁。

你想要进行对一组加锁的代码进行操作吗?想的话就先去抢到锁,拿到锁之后就可以对被加锁的代码为所欲为了,倘若拿不到锁的话就只能在代码块门口等着,因为等的线程太多了,这还成为了一种社会现象(状态),该社会现象被命名为线程的阻塞。

听上去很简单,但是实际上加锁有很多详细的规定的,详情政府发布了《关于synchronzied使用的若干规定》以及后来发布的《关于Lock使用的若干规定》。

线程和线程之间是共享内存的,当多线程对共享内存进行操作的时候有几个问题是难以避免的,竞态条件(race condition)和内存可见性。

**竞态条件:**当多线程访问和操作同一对象的时候,最终结果和执行时序有关,正确性是不能够人为控制的,可能正确也可能不正确。(如上文例子)

上文中说到的加锁就是为了解决这个问题,常见的解决方案有:

使用synchronized关键字

使用显式锁(Lock)

使用原子变量

**内存可见性:**关于内存可见性问题要先从内存和cpu的配合谈起,内存是一个硬件,执行速度比CPU慢几百倍,所以在计算机中,CPU在执行运算的时候,不会每次运算都和内存进行数据交互,而是先把一些数据写入CPU中的缓存区(寄存器和各级缓存),在结束之后写入内存。这个过程是及其快的,单线程下并没有任何问题。

但是在多线程下就出现了问题,一个线程对内存中的一个数据做出了修改,但是并没有及时写入内存(暂时存放在缓存中);这时候另一个线程对同样的数据进行修改的时候拿到的就是内存中还没有被修改的数据,也就是说一个线程对一个共享变量的修改,另一个线程不能马上看到,甚至永远看不到。

这就是内存的可见性问题。

解决这个问题的常见方法是:

使用volatile关键字

使用synchronized关键字或显式锁同步

同步代码块

每个java对象都有一个互斥锁标记,用来分配给线程,synchronized(o){ } 对o加锁的同步代码块,只有拿到锁标记的线程才能够进入对o加锁的同步代码块。

同步方法

synchronized作为方法修饰符修饰的方法被称为同步方法,表示对this加锁的同步代码块(整个方法都是一个代码块)。

JDK1.5的锁 Lock

ReentrantLock

ReentrantLock具有和synchronized相似的作用,但是更加的灵活和强大。

它是一个重入锁(synchronized也是),所谓重入就是可以重复进入同一个函数,这有什么用呢?

假设一种场景,一个递归函数,如果一个函数的锁只允许进入一次,那么线程在需要递归调用函数的时候,应该怎么办?退无可退,有不能重复进入加锁的函数,也就形成了一种新的死锁。

重入锁的出现就解决了这个问题,实现重入的方法也很简单,就是给锁添加一个计数器,一个线程拿到锁之后,每次拿锁都会计数器加1,每次释放减1,如果等于0那么就是真正的释放了锁。

ReadWriteLock

读写锁,读写分离。分为readLock和writeLock两把锁。对于readLock来说,是一把共享锁,可以多次分配;但是当readLock锁上的时候,调用writeLock是会阻塞的,反之亦然,另,写锁是一把普通的互斥锁,只可以分配一次。

synchronized和ReentrantLock的区别

两者都是互斥锁,所谓互斥锁:同一时间只有一个拿到锁的线程才能够去访问加锁的共享资源,其他的线程只能阻塞

都是重入锁,用计数器实现

ReentrantLock独有特点

ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁

ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程

ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制

volatile 修饰符 用来保证可见性

当一个共享变量被volatile修饰的时候,他会保证变量被修改之后立马在内存中更新,另一线程在取值的时候需要去内存中读取新的值。

注意:尽管volatile 可以保证变量的内存可见性,但是不能够保存原子性,对于b++这个操作来说,并不是一步到位的,而是分为好几步的,读取变量,定义常量1,变量b加1,结果同步到内存。虽然在每一步中获取的都是变量的最新值,但是没有保证b++的原子性,自然无法做到线程安全

猜你喜欢

转载自blog.csdn.net/jek123456/article/details/80429699