Java-5 - 新特性 - 锁

本文介绍Java并发编程的基础知识,包括ReentrantLock与Condition接口的使用方法,并通过生产者消费者模式和银行账户操作案例展示了如何利用这些工具解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java5 的 java.util.concurrent.locks锁 和 等待条件 提供一个框架的接口 和 类,它不同于内置同步和监视器。更灵活地使用锁和条件。


java.util.concurrent.locks包的接口:


|--   Lock接口--------替代了synchronized 方法和语句的使用。为 同步代码块 和 同步函数 提供了更广泛的 锁定 操作,将同步的隐示锁操作变成实现操作、

      |--   ReentrantLock类--------一个可重入的互斥锁Lock,它封装了隐示锁操作的方法,但功能更强大。(一个实现了Lock接口的类)

      |--   lock()--------获取锁、

      |--   unlock()------释放锁、


|--   Condition接口------替代了 Object 监视器方法的使用。对Object的监视器方法(waitnotifynotifyAll)进行单独封装,变成监视器对象,可以和任意Lock 实现组合使用。

      |--   await()------等待。throws InterruptedException、

       |--  signal()-----唤醒一个等待线程。

       |--   signalAll()---唤醒所有等待线程。

/*
	北京烤鸭制作和消费的实现	

	至少要有两个线程:
	1.生产烤鸭的线程
		生产线程的任务,生产烤鸭。
	2.消费烤鸭的线程
		消费线程的任务,消费烤鸭。
	
	1线程和2线程是两个不同对象,有两种不同的run方法,但是他们都是在操作同一资源。
	都是对共享资源烤鸭的操作,为了避免出现线程安全问题,我们要使用同步。

	可以把共享资源和对共享资源的操作方法封装在缓冲区。

	代码实现:
	1.创建一个缓冲区,
	2.创建两个线程任务,
	3.创建线程,
	4.开启线程。
*/

//简单烤鸭,生产一只,消费一只

//引入包。。。
import java.util.concurrent.locks.*;
class KaoYaTest  
{
	public static void main(String[] args) 
	{
		//创建共享资源对象
		KaoYaBuffer kaoya = new KaoYaBuffer();
		//创建生产任务
		ShengChang sc = new ShengChang(kaoya);
		//创建消费任务
		XiaoFei xf = new XiaoFei(kaoya);
		Thread t1 = new Thread(sc,"张三");//张三线程
		Thread t2 = new Thread(sc,"李四");
		Thread t3 = new Thread(xf,"王五");
		Thread t4 = new Thread(xf,"赵六");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}
//缓冲区
class KaoYaBuffer
{
	//创建一个互斥锁
	final Lock lock = new ReentrantLock();
	//创建生产监视器
	final Condition shengchang_condi  = lock.newCondition(); 
	//创建消费监视器
    final Condition xiaofei_condi = lock.newCondition(); 
	//烤鸭的名字
	private String name;
	//烤鸭的编号
	private int count = 1;
	//标记
	private boolean flag = false;
	//对烤鸭的生产操作
	public void set(String str){
		//获取锁
		lock.lock();
		try{
			while(flag)
				//当有烤鸭时,生产等待
				try{shengchang_condi.await();}catch(InterruptedException e){}	
			name = str + count;
			count++;
			System.out.println(Thread.currentThread().getName()+"生产"+name);
			flag = true;//把标记改成有烤鸭状态
			//唤醒消费线程
			xiaofei_condi.signal();
		}finally{
			//释放锁
			lock.unlock();
		}	
	}
	//对烤鸭的消费操作
	public void get(){
		lock.lock();
		try{
			while(!flag)
				try{xiaofei_condi.await();}catch(InterruptedException e){}
			System.out.println(Thread.currentThread().getName()+"消费"+name);
			flag = false;
			shengchang_condi.signal();
		}finally{
			lock.unlock();
		}	
	}
}
//生产线程任务
class ShengChang implements Runnable
{
	private KaoYaBuffer k;
	ShengChang(KaoYaBuffer k){
		this.k = k;	
	}
	public void run(){
		while(true){k.set("北京烤鸭");}	
	}	
}
//消费线程任务
class XiaoFei implements Runnable
{
	private KaoYaBuffer k;
	XiaoFei(KaoYaBuffer k){
		this.k = k;	
	}
	public void run(){
		while(true){k.get();}	
	}
}



/** 存钱取钱操作 **/

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* Java线程:锁
*
* @author leizhimin 2009-11-5 10:57:29
*/
public class Test {
        public static void main(String[] args) {
                //创建并发访问的账户
                MyCount myCount = new MyCount("95599200901215522", 10000);
                //创建一个锁对象
                ReadWriteLock lock = new ReentrantReadWriteLock(false);
                //创建一个线程池
                ExecutorService pool = Executors.newFixedThreadPool(2);
                //创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊
                User u1 = new User("张三", myCount, -4000, lock, false);
                User u2 = new User("张三他爹", myCount, 6000, lock, false);
                User u3 = new User("张三他弟", myCount, -8000, lock, false);
                User u4 = new User("张三", myCount, 800, lock, false);
                User u5 = new User("张三他爹", myCount, 0, lock, true);
                //在线程池中执行各个用户的操作
                pool.execute(u1);
                pool.execute(u2);
                pool.execute(u3);
                pool.execute(u4);
                pool.execute(u5);
                //关闭线程池
                pool.shutdown();
        }
}

/**
* 信用卡的用户
*/
class User implements Runnable {
        private String name;                //用户名
        private MyCount myCount;        //所要操作的账户
        private int iocash;                 //操作的金额,当然有正负之分了
        private ReadWriteLock myLock;                //执行操作所需的锁对象
        private boolean ischeck;        //是否查询

        User(String name, MyCount myCount, int iocash, ReadWriteLock myLock, boolean ischeck) {
                this.name = name;
                this.myCount = myCount;
                this.iocash = iocash;
                this.myLock = myLock;
                this.ischeck = ischeck;
        }

        public void run() {
                if (ischeck) {
                        //获取读锁
                        myLock.readLock().lock();
                        System.out.println("读:" + name + "正在查询" + myCount + "账户,当前金额为" + myCount.getCash());
                        //释放读锁
                        myLock.readLock().unlock();
                } else {
                        //获取写锁
                        myLock.writeLock().lock();
                        //执行现金业务
                        System.out.println("写:" + name + "正在操作" + myCount + "账户,金额为" + iocash + ",当前金额为" + myCount.getCash());
                        myCount.setCash(myCount.getCash() + iocash);
                        System.out.println("写:" + name + "操作" + myCount + "账户成功,金额为" + iocash + ",当前金额为" + myCount.getCash());
                        //释放写锁
                        myLock.writeLock().unlock();
                }
        }
}

/**
* 信用卡账户,可随意透支
*/
class MyCount {
        private String oid;         //账号
        private int cash;             //账户余额

        MyCount(String oid, int cash) {
                this.oid = oid;
                this.cash = cash;
        }

        public String getOid() {
                return oid;
        }

        public void setOid(String oid) {
                this.oid = oid;
        }

        public int getCash() {
                return cash;
        }

        public void setCash(int cash) {
                this.cash = cash;
        }

        @Override
        public String toString() {
                return "MyCount{" +
                                "oid='" + oid + '\'' +
                                ", cash=" + cash +
                                '}';
        }
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值