synchronized 笔记一

在开发游戏的野外BOSS战时,使用synchronized(Object o)锁定方法块,一时没注意,发生了并发数据异常。

package com.test;

import java.util.HashMap;
import java.util.Map;

public class TestRunnable implements Runnable{
	int num = 0;
	public TestRunnable(int num){
		this.num = num;
	}
	
	@Override
	public void run() {
		TestAction action = new TestAction();
		//参数:用户名
		action.action("user_"+num);
	}

	public static void main(String[] args) {
		for(int i=1;i<=10;i++){
			//10个线程,每个线程获取不同的User
			Thread t = new Thread(new TestRunnable(i));
			t.setName("thread"+i);
			t.start();
		}
	}
}

class TestAction {
	//全局唯一场景对象
	private static TestScene scene = new TestScene();
	
	public void action(String userName){
		TestUser user = scene.getUser(userName);
		//锁定对象是user,不同用户多线程并发调用时,场景唯一对象scene中的属性count数据异常
		synchronized (user) {
			scene.setCount(scene.getCount()+1);
		}
	}
}

class TestScene {

	int count = 0;
	private Map<String,TestUser> map = new HashMap<String,TestUser>() ;

	public TestScene(){
		init();
	}
	
	//初始化10个用户到场景中
	public void init(){
		for(int i=1;i<=10;i++){
			TestUser entity = new TestUser();
			entity.setName("user_"+i);
			map.put(entity.getName(), entity);
		}
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		System.out.println(Thread.currentThread().getName()+" old:"+this.count+" new:"+count);
		this.count = count;
	}

	public TestUser getUser(String name) {
		return map.get(name);
	}
}

class TestUser {

	Object lock = new Object();
	String name;

	public Object getLock() {
		return lock;
	}

	public void setLock(Object lock) {
		this.lock = lock;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
synchronized (Object o):在对象o上打开锁,方法块中的代码,应该只修改o的属性。如果需要修改其他对象的数据,需要根据实际情况,另外加锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值