重入锁与高并发

重入锁

ReentrantLock,是对synchronized的升级,synchronized是通过JVM实现的,ReentrantLock是通过JDK实现的。

重入锁的特点:

重入锁指可以给同一个资源添加多个锁,并且解锁的方式与synchronized也不同,synchronized的锁是当线程执行完业务逻辑之后自动释放,ReentrantLock的锁必须手动释放。

  1. 可重入,可以给同一个资源同时添加多把锁,对应的解锁的次数必须与上锁的次数相同,否则就会出现程序不继续执行的情况。

  2. 可中断,指某个线程在等待获取锁的过程中可主动终止线程。

  3. 限时性指可以判断某个线程在一定的时间段内能否获取锁,通过boolean tryLock(long time,TimeUnit unit)time表示时间数值,unit表示时间单位,返回值为boolean类型,true表示在该时间段内获取了锁,false表示在该时间段内没有获取锁。

高并发

并行和并发。

并发concurrency 并行parallelism

  • 并行: 指多个操作同时执行,判断程序是否处于并行状态,就看 同一个时刻是否有一个以上的工作单元在运行单线程是永远无法达到并行状态的。
  • 并发: 指的是程序的结构,处理并行的能力。如果一个系统称之为并发系统,则表示该系统采用了支持并发的设计模式,所以并发并不是指多个线程同时执行,它指的是一种人为设计的程序结构,可以处理多线程的能力。

高并发是指我们设计的程序,可以支持海量的任务在同一时间段内同时执行。

高并发的标准:

  1. QPS:每秒响应的http请求数量,QPS不等于并发量,并发数是指某时刻同时到到达服务器的请求数量。

  2. 吞吐量:单位时间内可以处理的请求数。

  3. 平均响应时间:系统对一个请求做出响应的平均时间。

    QPS = 并发数/平均响应时间。

  4. 并发用户数量:系统在正常运行情况可以承载的用户数量。

提供系统并发能力的两种方式:1.垂直扩展,水平扩展。

垂直扩展

提升单机的处理能力。

  1. 增强单机硬件性能。

  2. 提升单机架构性能。

水平扩展

系统集群(分层架构,nginx反向代理分担web应用服务器的压力,数据层主从复制,读写分离,分表分库,减轻数据库服务器的压力)


重入锁 —— 可重入

package Test1;

import java.util.concurrent.locks.ReentrantLock;

public class Test {
	public static void main(String[] args) {
		Account account = new Account();
		new Thread(account,"普通用户").start();
		new Thread(account,"超级用户").start();
	}
}

class Account implements Runnable {
	private int num;
	private ReentrantLock reentrantLock = new ReentrantLock();

	@Override
	public void run() {
		// TODO Auto-generated method stub
		reentrantLock.lock();
		reentrantLock.lock();	//这里锁住几次,下面就要解锁几次
		num++;
		try {
			Thread.currentThread().sleep(1000);
			System.out.println(Thread.currentThread().getName() + "是第" + num + "位访问");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			reentrantLock.unlock();
			reentrantLock.unlock();
		}
	}
}
返回上层目录

重入锁 —— 可中断

package Test1;

import java.util.concurrent.locks.ReentrantLock;

public class Test {
	public static void main(String[] args) {
		StopLock stopLock = new StopLock();
		Thread t1 = new Thread(stopLock,"线程1");
		Thread t2 = new Thread(stopLock,"线程2");
		t1.start();
		t2.start();
		try {
			Thread.currentThread().sleep(1000);//此处线程休眠1s,如果线程2还不能拿到资源则中断。//此处也可改为停6s,看效果。
			t2.interrupt();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class StopLock implements Runnable{
	private ReentrantLock reentrantLock = new ReentrantLock();
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			reentrantLock.lockInterruptibly();
			System.out.println(Thread.currentThread().getName()+"get lock");
			Thread.currentThread().sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			reentrantLock.unlock();
		}
	}
}

返回上层目录

重入锁 —— 限时性

package Test1;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
	public static void main(String[] args) {
		TimeLock timeLock = new TimeLock();
		new Thread(timeLock).start();
		new Thread(timeLock).start();
	}
}

class TimeLock implements Runnable{
	private ReentrantLock reentrantLock = new ReentrantLock();
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			if(reentrantLock.tryLock(3, TimeUnit.SECONDS)) {
				System.out.println(Thread.currentThread().getName()+"get lock");
				Thread.currentThread().sleep(5000);
			}else {
				System.out.println(Thread.currentThread().getName()+"not get lock");
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(reentrantLock.isHeldByCurrentThread()) {
				reentrantLock.unlock();
			}
		}
	}
}
返回上层目录

返回多线程目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值