synchronized 关键字 使用
1. 把非线程安全的变成线程安全的。在方法名前面加上该关键字即可。
public synchronized String getContent(){
return null ;
}
虽然这两种方法中都可以形成线程安全,但是如果在操作中不当,也会出现线程不安全的结果。我们在方法中有锁,如果我们在该类上创建多个实例,那么锁的作用就会消失。还会出现线程不安全的状况。在项目中如果方法中加锁,最好采用的是同一个类或者是静态方法,这样保证使用的是同一个锁,不会是多个锁。保证了线程安全的问题。方法上加锁,如果在方法中有很多代码其实不需要执行同步操作,只是一部分需要同步操作,在整个方法上加锁,就容易导致该方法区的内容运行过慢,效率降低。
public static synchronized String getContent(){
return null ;
}
2. 使用该关键字,形成同步代码块。
同步代码块可以帮助解决上面的问题。将一部分同步,一部分异步.这样同步的地方就可以并行执行,增大效率。
public String getContent(Object object){
Stirng result ;
synchronized (Object.class){
return null ;
}
return result;
}
3. 同步代码块与在方法区上使用synchronized关键字的作用
4. 同步代码块还支持其他对象来实现同步的功能
volatile 关键字
* 使变量在多个线程之间可见。我们都是到在线程中会有私有堆栈和共有堆栈,那么volatile 的作用就是让其在线程访问变量时,强制性的从共有堆栈中取值。也就是我们平常所说的主内存而不是线程工作内容中读取,保证了线程安全的可见性。但是只是保证可见性,不保证原子性。没有同步特性。
Lock的使用
1. ReentrantLock 介绍
ReentrantLock 可以达到我们使用synchronized 锁达到的同步效果 ,并且还能扩展更强大。在使用中我们一般使用的是以下一些方法。并且该锁是一个完全互斥拍他的锁。读写不分离
public void getContent(Integer value ){
try{
lock.lock();
lock.getHoldCount(); //查询当前线程保持的此锁定的个数。也就是调用lock()方法的次数。
lock.getQueueLength(); // 返回挣等待获取此锁定 的线程估计数。
lock.getWaitQueueLength(condition); //返回等待与此锁定相关条件Condition估计数。
lock.hasQueuedThread(Thread threads) ; //作用查询指定的线程是否在等待获取此锁定
lock.hasQueuedThreads(); //查询 是否有线程正在等待获取此锁定。
lock.hasWaiters(condition); // 查询是否有线程正在等待此锁定有关的condition条件。
lock.isFair(); // 判断是不是公平锁
lock.isHeldByCurrentThread(); // 查询当前线程是否保持此锁定
lock.isLocked(); //作用是查询此锁定是否由任意线程保持。
lock.lockInterruptibly(); // 如果当前线程未被中断,则获取锁定。如果已经被中断则出现异常
lock.tryLock(); //仅在 调用时锁定未被另一个线程保持的情况下,才获取该锁定
System.out.println("打印内容: " + Instant.now());
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
2. ReentrantReadWriteLock 读写锁
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
readWriteLock.readLock().lock();
readWriteLock.writeLock().lock();