可重入锁是锁的一个相关概念,并不是特指我们的ReentrantLock,而是如果一个锁具备可重入性,那我们就说这是一个可重入锁。ReentrantLock和synchronized都是可重入锁。至于什么是可重入性,这里举个简单的例子,现在在一个类里我们有两个方法(代码如下)
一个叫做去北京,一个叫做买票,那我们在去北京的方法里可以直接调用买票方法,假如两个方法全都用synchronized修饰的话,在执行去北京的方法,线程获取了对象的锁,接着执行买票方法,如果synchronized不具备可重入性,那么线程已经有这个对象的锁了,现在又来申请,就会导致线程永远等待无法获取到锁。而synchronized和ReentrantLock都是可重入锁,就不会出现上述的问题。
class Trip {
public synchronized void goToBeiJing() {
// 去北京
buyATicket();
}
public synchronized void buyATicket() {
// 买票
}
}
二者都是可重入锁,那么为什么要有两个呢?既然存在,那么就一定是有意义的。synchronized是Java中的一个关键字,而Lock是Java1.5后在java.util.concurrent.locks包下提供的一种实现同步的方法,那么显然的,synchronized一定是有什么做不到的或者缺陷,才导致了Lock的诞生。
public interface Lock {
// 下面这些是用来获得锁的方法:
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
//下面这一个是用来释放锁的方法:
Condition newCondition();
}
ReentrantLock
是Lock的一个实现类(另外两个实现类是ReentrantReadWriteLock类下的两个静态内部类:WriteLock和ReadLock),它的意思是可重入锁,可重入锁前面已经讲过了。ReentrantLock中提供了更多的一些方法。不过常用的就是Lock中的这些。lock()
、tryLock()
、tryLock(long time, TimeUnit unit)
和lockInterruptibly()
是用来获取锁的。unLock()
方法是用来释放锁的。
lock.lock();
try{
// 处理
}catch(Exception ex){
// 捕获异常
}finally{
// 释放锁
lock.unlock();
}
if (lock.tryLock()) {
try{
// 处理
}catch(Exception ex){
// 捕获异常
}finally{
// 释放锁
lock.unlock();
}
}
lockInterruptibly()就比较特殊了,它表示可被中断的,意思就是,当尝试获取锁的时候,如果获取不到的话就会等待,但是,在等待的过程中它是可以响应中断的,也就是中断线程的等待过程。使用形式的话一样用try catch处理,就不贴代码了。
public interface ReadWriteLock {
2 Lock readLock();
3
4 Lock writeLock();
5 }
public class Main {
public static void main(String[] args) {
final Main m = new Main();
new Thread(){
public void run() {
m.read(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
m.read(Thread.currentThread());
};
}.start();
}
public synchronized void read(Thread thread) {
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime <= 1) {
System.out.println(thread.getName()+"线程在进行读操作");
}
System.out.println(thread.getName()+"线程完成读操作");
}
}
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程完成读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程完成读操作
public class Main {
public static void main(String[] args) {
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
final Main m = new Main();
new Thread(){
public void run() {
m.read(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
m.read(Thread.currentThread());
};
}.start();
}
public void read(Thread thread) {
readWriteLock.readLock().lock();
try {
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime <= 1) {
System.out.println(thread.getName()+"线程在进行读操作");
}
System.out.println(thread.getName()+"线程完成读操作");
} finally {
readWriteLock.unlock();
}
}
}
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程在进行读操作
Thread-1线程在进行读操作
Thread-0线程完成读操作
Thread-1线程完成读操作
//主方法
public class Demo01 {
public static void main(String[] args) {
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.start();
thread2.start();
}
}
//100以内的偶数
class Thread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i%2==0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
//100以内的奇数
class Thread2 extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i%2!=0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class Demo02 {
public static void main(String[] args) {
//打印0~100内的偶数
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i%2==0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}.start();
//打印0~100内的奇数
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i%2!=0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}.start();
}
}
package 任务十__多线程;
/** * @author ${范涛之} * @Description * @create 2021-11-23 21:30 */
public class Test {
public static void main(String[] args) {
Myfriend w1 = new Myfriend("范涛之 ");
Myfriend w2 = new Myfriend("秦书翔 ");
Myfriend w3 = new Myfriend("张容康 ");
w1.start();
w2.start();
w3.start();
}
}
class Myfriend extends Thread{
//这里票的数量应该是静态变量,否则每个对象创建后都有100张票,而不是总共100张票
private static int tickets = 100;
public Myfriend(String name) {
super(name);
}
@Override
public void run() {
while (tickets > 0){
tickets--;
System.out.println(getName() + "卖出了一张票,剩余票数:" + tickets);
}
}
}
注意:高优先级的线程要抢占低优先级线程CPU的执行权。但是只是从概率上来讲,高优先级的线程高概率的情况下被执行。并不意味着只有当高优先级的线程被执行完以后,低优先级的线程才会被执行。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/justleavel/article/details/121489455
内容来源于网络,如有侵权,请联系作者删除!
ReentrantLock
是Lock的一个实现类(另外两个实现类是ReentrantReadWriteLock类下的两个静态内部类:WriteLock和ReadLock),它的意思是可重入锁,可重入锁前面已经讲过了。ReentrantLock中提供了更多的一些方法。不过常用的就是Lock中的这些。lock()
、tryLock()
、tryLock(long time, TimeUnit unit)
和lockInterruptibly()
是用来获取锁的。unLock()
方法是用来释放锁的。