• 悲观锁:认为资源非常紧张,遇到共享中的资源直接挂起线程,等待唤醒。例如synchronized
  • 乐观锁:认为资源很可能不紧张,遇到共享资源直接执行操作,如果结果与预期不一致则再次尝试,循环直到成功。例如CAS

悲观锁遇到资源不紧张时,挂起唤醒线程相对来说资源消耗过大;乐观锁遇到资源紧张时执行一直无法成功,cpu自旋,消耗过大。


  • 公平锁指的是锁释放时,排队中的线程先lock的先获得锁。
  • 非公平锁指的是锁释放时,排队中的线程随机取一个获得锁。

  • 一个线程获得读锁,其他线程也可以获得读锁,但不能获得写锁。
  • 一个线程获得写锁,其他线程既不能读也不能写。

竞态条件

多个线程操作共享对象时,由于操作顺序的原因可能导致预期之外的结果,称为竞态条件。

存在竞态条件的代码段称为临界区。

解除方法是加锁(synchronized或者lock) 


加锁方式 

//synchronized方式
synchronized(String.class){
    System.out.println("b");
}
synchronized(ob){
    System.out.println("b");
}
public synchronized void getSyn(){}

//Lock方式
Lock lock=new ReentrantLock();
lock.lock();
lock.unlock();
lock.lockInterruptibly();//此方法类似于lock(),但是可以响应interrupt()抛出异常
lock.unlock();
        
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
rwLock.readLock().lock();
rwLock.readLock().unlock();
rwLock.writeLock().lock();
rwLock.writeLock().unlock();

synchronized和Lock的异同

相同点: synchronized、ReentrantLock都是独占锁,默认都是非公平锁(解锁后随机分配新锁)

不同点:

  1. synchronized是在虚拟机层面实现(字节码中代码块上下被monitorenter、monitorexit包围,只有一个线程能访问),Lock是通过类实现
  2. synchronized自动释放,Lock都需要手动释放unlock();
  3. ReentrantLock还可以实现公平锁(new ReentrantLock(true););ReentrantLock还可以实现tryLock();ReentrantReadWriteLock还可以实现读写锁;

死锁示例

    static void deadLockTest(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(String.class){
                    Math.random(); //拖延时间,更容易进入死锁状态
                    synchronized(int.class){
                        System.out.println("a");
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(int.class){
                    synchronized(String.class){
                        System.out.println("b");
                    }
                }
            }
        }).start();
    }

停止线程

  • t.stop()
  • t.interrupt()

注意interrupt()本身不会直接终止线程,有两种情况:

  1. 线程正在正常运行,此时interrupt()只是将线程标记为interrupted状态,可以用while (!Thread.currentThread().isInterrupted()){}来捕获状态终止循环,借此终止线程。
  2. 线程正在sleep()/wait()/join()状态,此时interrupt()将在子线程中抛出一个InterruptedException,可以用try  catch捕获错误终止线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值