有两种机制防止代码块受并发访问的干扰:
1、一个是使用synchronized关键字。
2、使用ReentrantLock类。(通过显示定义同步锁对象来实现同步。)
同步锁(lock)方法是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前先获得Lock对象。
Lock、ReadWriteLock(读写锁)是java 5 提供的两个根接口。别为Lock接口提供了ReentrantLock(可重入锁)实现类;为ReadWriteLock接口提供了ReentrantReadWriteLock实现类。
在实现线程安全的控制中,比较常用的是ReentrantLock(可重入锁)。使用该Lock对象可以显示地加锁、释放锁。
1 import java.util.*; 2 import java.util.concurrent.locks.ReentrantLock; 3 public class Other extends Thread{ 4 private Account account; 5 private double drawAmount; 6 //private String name; 7 public Other(Account account,double drawAmount,String name){ 8 super(name);//必须是第一语句 9 this.account=account; 10 this.drawAmount=drawAmount; 11 start(); 12 } 13 public void run(){ 14 for(int i=0;i<15;i++){ 15 account.draw(drawAmount); 16 } 17 } 18 public static void main(String[] args){ 19 Account a=new Account("刘腾",10000); 20 Other o=new Other(a,1000,"A"); 21 Thread t=new Thread(new RunnableClass(a)); 22 t.setName("B"); 23 t.start(); 24 } 25 } 26 class Account{ 27 //定义锁对象 28 private final ReentrantLock lock=new ReentrantLock(); 29 private String name; 30 private double money; 31 public Account(){} 32 public Account(String name,double money){ 33 this.name=name; 34 this.money=money; 35 } 36 public double getMoney(){ 37 lock.lock(); 38 try{ 39 return money;} 40 finally{ 41 lock.unlock(); 42 } 43 } 44 public void draw(double drawAmount){ 45 lock.lock(); 46 try{ 47 if(money>=drawAmount){ 48 System.out.println(name +"取钱成功!吐出钞票:"+drawAmount); 49 try{ 50 Thread.sleep(1000); 51 }catch(Exception e){ 52 System.out.println(e); 53 } 54 money-=drawAmount; 55 System.out.println("余额为:"+getMoney()); 56 }else{ 57 System.out.println("取钱失败!余额不足!"); 58 } 59 }finally{ 60 lock.unlock(); 61 } 62 } 63 } 64 class RunnableClass implements Runnable{ 65 private Account account; 66 //private double drawAmount; 67 public RunnableClass(Account account){ 68 this.account=account; 69 //this.drawAmount=drawAmount; 70 } 71 public void run (){ 72 for(int k=0;k<10;k++){ 73 try{ 74 Thread.sleep(1000); 75 System.out.println(Thread.currentThread().getName()+"读取钱数为:"+account.getMoney());} 76 catch(Exception e){} 77 } 78 } 79 }
需要导入import java.util.concurrent.locks.ReentrantLock;
时间: 2024-10-08 10:34:43