-
Notifications
You must be signed in to change notification settings - Fork 780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2019-07-31:谈一谈java线程常见的几种锁? #110
Comments
4种Java线程锁(线程同步)
|
还有一个 unsafe 类; |
锁首先,Java为什么会出现锁的概念,锁是用来干什么的?这里我给大家解释一下,锁 是保证 线程同步与安全的. synchronizedsynchronized 有什么用?大家看一下这段代码 public class Synchronized2Demo implements TestDemo {
private int x = 0;
private void count() {
x++;
}
@Override
public void runTest() {
new Thread() {
@Override
public void run() {
for (int i = 0; i < 1_000_000; i++) {
count();
}
System.out.println("final x from 1: " + x);
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 0; i < 1_000_000; i++) {
count();
}
System.out.println("final x from 2: " + x);
}
}.start();
}
} synchronized的互斥访问当添加 synchronized 的时候,多个线程不能同时访问同一个方法,synchronized 的意义是保证方法或代码块的内部资源的互斥访问,同一时间用用一个monitor监视代码最多一个代码访问,怎么解释这句话呢? 运行上段代码,我们不难发现: final x from 1: 1000000
final x from 2: 1314570 Fuck! 竟然结果不是200 0000,而且每次结果都不一样,这是为什么呢? 因为:x++ 不是原子操作, 不是一行代码执行的,他是可以分解的代码,可以分离成这样
你看,这是两段代码吧,加 synchronized 修饰 就可以完美解决这个问题. synchronized 的本质:
Lock / ReentrantReadWriteLock同样是加锁机制 ,使用方式更加灵活,同时也更加麻烦一些
Lock lock = new ReentrantLock();
{
// -------伪代码-------
}
lock.lock(); try {
x++;
} finally {
lock.unlock();
} finally 作用是保证在方法提前结束或出现Exception的时候,依然能正常释放锁. 一般不会直接使用 Lock,而是直接使用更加复杂的锁,如: ReadWriteLock: public class ReadWriteLockDemo implements TestDemo {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
private int x = 0;
@Override
public void runTest() {
print(15);
count();
}
public void count() {
writeLock.lock();
try {
x++;
} finally {
writeLock.unlock();
}
}
public void print(int time) {
readLock.lock();
try {
for (int i = 0; i < time; i++) {
System.out.println(x + "");
}
System.out.println("over");
} finally {
readLock.unlock();
}
}
} volatile
java.util.concurrent.atomic
AtomicInteger atomicInteger = new AtomicInteger(0);
{
// -------伪代码--------
}
atomicInteger.getAndIncrement(); 解决了 ++ 原子性 问题,非常好用. 悲观锁不管数据怎么样我都会加锁,这个就是悲观锁 乐观锁我认为,别人不会读数据我倾向于别人不会动数据,所以不对代码块加锁,这就是乐观锁 线程安全问题的本质:在多线程访问共同资源时,在某一个线程对资源进行写操作中途(写入已经开始了,但还没结束),其他线程对这个写了一半资源进行读操作,或基于这个写了一半的资源进行了写操作,导致出现数据错误 锁机制的本质:通过共享资源进行访问限制,让同一时间只有一个线程可以访问资源,保证数据的准确性 总结:无论是线程安全问题,还是针对线程衍生的锁机制,它的核心在于共享资源,而不是某个方法或几行代码 当然还有死锁问题,这里我就不一一和大家阐述了. 最后大家觉的我的内容对大家有帮助,欢迎通过以下渠道阅读我的文章或github star +1
|
比如:
当然也可以是其他锁
The text was updated successfully, but these errors were encountered: