Java多线程 Concurrent并发包——Lock

传统的线程协作   Thread 、Executor、 ForkJoin

——线程任务启动-》执行-》结束

——线程间缺乏协作

Synchronized同步

——同时限定一个线程进入关键区 性能损失较大

Lock

——java.lang.concurrent.lock包提供同步的效果

——实现更为复杂的临界区结构

——tryLock方法预判锁是否空闲

——允许读写锁分离  符合 多个读 单个写的并发思想

——ReentrantLock 可重入的互斥锁

——ReentrantReadWriteLock 可重入的读写锁

(可重入 : 支持对资源重复加锁)

——lock unlock 获取 释放锁

 

实例演示:

 

     * 问题模拟:
     * 奶茶店
     * 买奶茶的人如果看到需要排队 则不买
     * 假设奶茶店 有多名员工   一个订单本
     * 老伴负责写新订单 员工不断查看订单制作奶茶 写的期间不允许查看  (仅允许单个写)
     * 多个员工可同时查看订单  查看时老板不允许写新订单   (可多个读)

 

private static final ReentrantLock queueLock=new ReentrantLock();//可重入锁
private static final ReentrantReadWriteLock orderLock=new ReentrantReadWriteLock();
public static void main(String[] args) throws InterruptedException 
{
		
		//buyMikeTea();
		handleOrder();

}

 

买奶茶模拟  10个人依次抢夺锁 购买

public void tryToBuyMikeTea() throws InterruptedException
	{
		boolean flag=true;
		while(flag)
		{
			//tryLock方法 检查是否可获得锁 可以就获取
			if(queueLock.tryLock())
			{
				long thinkingTime=(long)(Math.random()*500);
				Thread.sleep(thinkingTime);
				System.out.println(Thread.currentThread().getName()+": 我需要一杯奶茶");
				flag=false;
				queueLock.unlock();//释放锁
			}
			else
			{
				System.out.println(Thread.currentThread().getName()+":再等等");
				
			}
			if(flag)
			{
				Thread.sleep(1000);
			}
		}
	}

 

 

public static void buyMikeTea() throws InterruptedException
	{
		LockExample lockExample=new LockExample();
		int STUDENTS_CNT=10;
		Thread[] students=new Thread[STUDENTS_CNT];
		for(int i=0;i

执行结果:10个线程依次互斥完成购买 

Java多线程 Concurrent并发包——Lock_第1张图片

 

 

读写锁模拟  同一时间只允许一个线程写 可允许多个线程读

 

    public void addOrder() throws InterruptedException
	{
		orderLock.writeLock().lock(); //添加写锁
		long writingTime=(long)(Math.random()*1000);
		Thread.sleep(writingTime);
		System.out.println("老板加一笔新订单");
		orderLock.writeLock().unlock();//释放锁
	}
	public void viewOrder() throws InterruptedException
	{
		orderLock.readLock().lock();
		long readingTime=(long)(Math.random()*500);
		Thread.sleep(readingTime);
		System.out.println(Thread.currentThread().getName()+":查看订单本");
		orderLock.readLock().unlock();
	}

 

public static void handleOrder() throws InterruptedException
	{
		LockExample lockExample=new LockExample();
		Thread boss=new Thread(
				new Runnable()
				{
					@Override
					public void run()
					{
						while(true)
						{
							try
							{
								lockExample.addOrder();
								long waitingTime=(long)(Math.random()*1000);
								Thread.sleep(waitingTime);
							}catch(InterruptedException e)
							{
								e.printStackTrace();
							}
						}
					}
				}
				);
		boss.start();
		int workerCnt=3;
		Thread[] workers=new Thread[workerCnt];//店员线程负责生产
		for(int i=0;i<=workerCnt;i++)
		{
			workers[i]=new Thread(
					new Runnable()
					{
						@Override
						public void run()
						{
							while(true)
							{
								try
								{
									lockExample.viewOrder();
									long workingTime=(long)(Math.random()*1000);
									Thread.sleep(workingTime);
								}catch(InterruptedException e)
								{
									e.printStackTrace();
								}
							}
						}
					}
					);
			workers[i].start();
		}

执行结果:

 

Java多线程 Concurrent并发包——Lock_第2张图片

 

你可能感兴趣的:(Java多线程,后端开发)