Java多线程同步---------银行取存款实例

转载:

https://blog.csdn.net/wenwen091100304/article/details/48318699

1.不同步时的代码:

Bank类:

package com;

public class Bank {

	private int count=0;
	
	
	//存钱
	public void addMoney(int money) {
		count+=money;
		System.out.println("成功存进银行"+money+"元");
	}
	
	public void subMoney(int money) {
		if(count>=money) {	
			count-=money;
			System.out.println("成功取出"+money+"元");
		}else {
			System.out.println("余额不足");
		}
	}
	
	public void lookMoney() {
		System.out.println("账户余额:"+count);
	}
}

测试类:

package com;

public class BankTest {

	public static void main(String[] args) {

		final Bank bank=new Bank();
		Thread tadd=new Thread(new Runnable() {

			public void run() {

				while(true) {
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					bank.addMoney(100);
					bank.lookMoney();
					System.out.println("\n");
				}
			}
			
		});
		Thread tsub=new Thread(new Runnable() {

			public void run() {
				while(true) {
					bank.subMoney(100);
					bank.lookMoney();
					System.out.println("\n");
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				}
			}
			
		});
		
		tsub.start();
		tadd.start();
	}

}

运行结果:

余额不足
账户余额:0


成功存进银行100元
账户余额:100


成功取出100元
账户余额:0


余额不足
账户余额:0


成功存进银行100元
账户余额:100


成功存进银行100元
成功取出100元
账户余额:100


账户余额:100


成功存进银行100元
成功取出100元
账户余额:100


账户余额:100


成功存进银行100元
成功取出100元
账户余额:100


账户余额:100


2.同步时的代码:

第一种:

synchronized 关键字修饰方法

由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

package com;

public class Bank {

	private int count=0;
	
	
	//存钱
	public synchronized void addMoney(int money) {
		count+=money;
		System.out.println("成功存进银行"+money+"元");
	}
	
	public synchronized void subMoney(int money) {
		if(count>=money) {	
			count-=money;
			System.out.println("成功取出"+money+"元");
		}else {
			System.out.println("余额不足");
		}
	}
	
	public void lookMoney() {
		System.out.println("账户余额:"+count);
	}
}

运行结果:

余额不足
账户余额:0


余额不足
账户余额:0


成功存进银行100元
账户余额:100


成功存进银行100元
账户余额:100


成功取出100元
账户余额:100


成功取出100元
账户余额:0


成功存进银行100元
账户余额:100


成功存进银行100元
账户余额:100


成功取出100元
账户余额:100


成功存进银行100元
账户余额:200


成功取出100元
账户余额:100


成功取出100元
账户余额:0


成功存进银行100元
账户余额:100


成功取出100元
账户余额:0


成功存进银行100元
账户余额:100


成功存进银行100元
成功取出100元
账户余额:100


账户余额:100


注意:

      synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类 

第二种:

synchronized关键字同步代码块:

package com;

public class Bank {

	private int count=0;
	
	
	//存钱
	public  void addMoney(int money) {
		
		synchronized(this) {
			count+=money;
		}
		System.out.println("成功存进银行"+money+"元");
	}
	
	public  void subMoney(int money) {
		synchronized(this) {
			
		if(count>=money) {	
				count-=money;
				System.out.println("成功取出"+money+"元");
			}else {
				System.out.println("余额不足");
			}
		}
	}
	
	public void lookMoney() {
		System.out.println("账户余额:"+count);
	}
}
余额不足
账户余额:0


成功存进银行100元
账户余额:100


成功取出100元
账户余额:0


成功存进银行100元
成功取出100元
账户余额:0


账户余额:0


成功存进银行100元
账户余额:0


成功取出100元
账户余额:0


3.volatile关键字

它的原理是每次要线程要访问volatile修饰的变量时都是从内存中读取,而不是从缓存当中读取,因此每个线程访问到的变量值都是一样的。这样就保证了同步。

  • volatile关键字为域变量的访问提供了一种免锁机制 
  • 使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新 
  • 因此每次使用该域就要重新计算,而不是使用寄存器中的值 
  • volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

 

 运行结果:

余额不足
账户余额:0


余额不足
成功存进银行100元
账户余额:100


账户余额:100


成功取出100元
账户余额:100


成功存进银行100元
账户余额:100


成功取出100元
账户余额:0


成功存进银行100元
账户余额:100


成功取出100元
成功存进银行100元
账户余额:200


账户余额:200


成功存进银行100元
账户余额:200


成功取出100元
账户余额:200


猜你喜欢

转载自blog.csdn.net/yongbutingxide/article/details/82721227