Synchronized Statements作用

先来看下lock的作用

intrinsic Locks and Synchronization

Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.") Intrinsic locks play a role in both aspects of synchronization: enforcing exclusive access to an object's state and establishing happens-before relationships that are essential to visibility.

Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

When a thread releases an intrinsic lock, a happens-before relationship is established between that action and any subsequent acquistion of the same lock.

我写了一个程序可以体会一下


账户account

package com.yuxuan.j2se;
/*
 * 账户
 */
public class Account {
private Integer price=300;

public void deductPrice(Integer price) {
	this.price = this.price-price;
}

public void addPrice(Integer price) {
	this.price = this.price+price;
}

public Integer getPrice() {
	return price;
}

public void setPrice(Integer price) {
	this.price = price;
}


}

person1

package com.yuxuan.j2se;

public class Person1 implements Runnable{
private Account account;

public Person1(Account account) {
	super();
	this.account = account;
}

@Override
public void run() {
synchronized (account) {
	
	System.out.println("person1原account价格"+account.getPrice());
	account.addPrice(100);
	System.out.println("person1存入100acount后,account价格"+account.getPrice());
	try {
		
		Thread.currentThread().sleep(5000);
		
		System.out.println("person1睡了5秒后,account价格"+account.getPrice());
		
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

	
	
}

}

Person2

package com.yuxuan.j2se;

public class Person2 implements Runnable{
private Account account;

public Person2(Account account) {
	super();
	this.account = account;
}

@Override
public void run() {
	synchronized (account) {
		
		System.out.println("person2原account价格"+account.getPrice());
		account.addPrice(200);
		System.out.println("person2存入200后,account价格"+account.getPrice());
		try {
			
			Thread.currentThread().sleep(3000);
			System.out.println("person2睡3秒后,accout价格"+account.getPrice());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
}

}


person3

package com.yuxuan.j2se;

public class Person3 implements Runnable{
private Account account;

public Person3(Account account) {
	super();
	this.account = account;
}

@Override
public void run() {
	synchronized (account) {
		
		System.out.println("person3原account价格"+account.getPrice());
		account.deductPrice(200);
		System.out.println("person3扣除200后,account价格"+account.getPrice());
		try {
			
			Thread.currentThread().sleep(5000);
			System.out.println("person3睡5秒后,account价格"+account.getPrice());
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	
}

}

Test

package com.yuxuan.j2se;

public class TestAccount {
 public static void main(String[] args) throws InterruptedException {
	Account account =  new Account();
	Thread thread1 = new Thread(new Person1(account));
	Thread thread2 = new Thread(new Person2(account));
	Thread thread3 = new Thread(new Person3(account));
	thread1.start();
	thread2.start();
	thread3.start();

}
}

你会看到像下面的输出

person1原account价格300
person1存入100acount后,account价格400
person1睡了5秒后,account价格400
person3原account价格400
person3扣除200后,account价格200
person3睡5秒后,account价格200
person2原account价格200
person2存入200后,account价格400
person2睡3秒后,accout价格400

上面没有看到什么不对的地方


而如果把Person1,person2,person3里面的

synchronized (account) {
}
去掉,改成如

public void run() {
	
		
		System.out.println("person3原account价格"+account.getPrice());
		account.deductPrice(200);
		System.out.println("person3扣除200后,account价格"+account.getPrice());
		try {
			
			Thread.currentThread().sleep(5000);
			System.out.println("person3睡5秒后,account价格"+account.getPrice());
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	


你会看到像下面的输出,

person1原account价格300
person3原account价格300
person2原account价格300
person3扣除200后,account价格200
person1存入100acount后,account价格400
person2存入200后,account价格400
person2睡3秒后,accout价格400
person1睡了5秒后,account价格400
person3睡5秒后,account价格400

person3绝对很乐意这样做,300块,取出了200块,还剩200!这就是应为没加synchronized (account) {}

导致钱显示的不正确


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值