Java多线程随手记——各种锁

 


由于同一进程中线程间的数据资源是共享的,因此常常会导致资源数据做出不被期望的更改,这时,便需要引入锁,来使得数据同步。

public class SynchronizedDemo {
	
	private int a ;
	public SynchronizedDemo(){
		this.a=1;
	}
	public void setA(int a){
		this.a=a;
	}	
	private void calculate(){
		this.a = a*2;
	}
	public  void getA(){
		System.out.println("Thread:"+Thread.currentThread().getId()+",a="+a);
	}
	
	public void print(){		
	      calculate();
		  getA();
			
	}
	public static void main(String args[]){
		final SynchronizedDemo demo= new SynchronizedDemo();
		for(int i=0;i<10;i++)
		{		
			new Thread(){
				@Override
				public void run() {
					// TODO Auto-generated method stub
					demo.print(); 
				}			
			}.start();
		}
	}

}

上面的code是没有加上锁,这时输出结果为

Thread:8,a=2
Thread:10,a=4
Thread:9,a=8
Thread:11,a=16
Thread:12,a=32
Thread:13,a=64
Thread:14,a=128
Thread:15,a=512
Thread:16,a=512
Thread:17,a=1024

可以看到,输出结果中出现了两个512。原因便是,在其中一个线程在读取到a值为128并对其做出修改之前,另一个线程也读取了a值128。

这边产生了冲突,导致了数据的不一致性。

解决的方法其实不唯一,这里介绍使用锁来进行保障。

java中提供了synchronized 关键字,来限制只有一个线程可以访问该代码块或者方法,这个关键字可以使用的方式有两种。

	public synchronized void print(){		
	      calculate();
		  getA();
			
	}
	public  void print(){		
	synchronized(this){
	      calculate();
		  getA();
		}		
	}

只有前一个线程访问结束后,下一个线程才能继续访问。

Thread:9,a=2
Thread:11,a=4
Thread:14,a=8
Thread:12,a=16
Thread:8,a=32
Thread:10,a=64
Thread:13,a=128
Thread:15,a=256
Thread:16,a=512
Thread:17,a=1024

多次试验后,可以看到得到的结果是无误的。

 

同时,在JDK1.5版本以后,增加了concurrent包,专门用于处理线程。

	private Lock lock = new ReentrantLock();
	public  void print(){		
		  lock.lock();
	      calculate();
		  getA();	 
		  lock.unlock();
	}

ReentrantLock便是其中实现一个锁。

相对于synchronized,听说ReentrantLock更为高效些,还未作出验证,下次抽空一定得验证下,再编辑修正。

本文如果有错误的地方,请及时指正,谢谢

下一章:ReentrantLock的源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值