synchronized与lock

本文介绍了一个使用ReentrantLock实现的简单并发编程案例,演示了如何通过显式锁保证多线程环境下的数据一致性,并对比了synchronized关键字与ReentrantLock的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestLock {
private static Lock lock = new ReentrantLock();
private int id;
private static User user = new User();
private Log log = LogFactory.getLog(TestLock.class);
TestLock(int id){
this.id = id;
}
public void inc(long cur,int id){
//lock.lock();
user.cur = cur;
log.info("线程" + id + "传入"+ cur);

log.info("线程" + id + "获取"+ user.cur);
//lock.unlock();
}
public Lock getLock(){
return lock;
}


}


import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class TestClient {
IncThread t1,t2,t3,t4;
private Log log = LogFactory.getLog(TestClient.class);
TestClient(){
t1 = new IncThread(1);
t2 = new IncThread(2);
t3 = new IncThread(3);
t4 = new IncThread(4);

}
public void test(){
t1.start();
t2.start();
t3.start();
t4.start();
}
class IncThread extends Thread{
int id;
IncThread(int id){
this.id = id;
}
public void run(){
TestLock t = new TestLock(id);

for(int i=0; i<10;i++){
Random a = new Random();
int cur = a.nextInt(100)+1;
log.info("线程"+id+ "生成" + cur);
t.inc(cur,id);
}
}
}

public static void main(String args[]){
TestClient client = new TestClient();
client.test();
System.out.println("3333333");

}
}



output:
3333333
2013-04-06 16:07:32 [dingchd.multithread.TestClient-36]-[INFO] 线程4生成26
2013-04-06 16:07:32 [dingchd.multithread.TestClient-36]-[INFO] 线程2生成58
2013-04-06 16:07:32 [dingchd.multithread.TestClient-36]-[INFO] 线程3生成69
2013-04-06 16:07:32 [dingchd.multithread.TestClient-36]-[INFO] 线程1生成53
2013-04-06 16:07:32 [dingchd.multithread.TestLock-20]-[INFO] 线程3传入69
2013-04-06 16:07:32 [dingchd.multithread.TestLock-22]-[INFO] 线程3获取53

线程3 传入69之后,获取的是线程1传入的值,未同步;
加上lock锁之后的output:
3333333
2013-04-06 16:18:17 [dingchd.multithread.TestClient-40]-[INFO] 线程1生成27
2013-04-06 16:18:17 [dingchd.multithread.TestClient-40]-[INFO] 线程2生成22
2013-04-06 16:18:17 [dingchd.multithread.TestClient-40]-[INFO] 线程4生成95
2013-04-06 16:18:17 [dingchd.multithread.TestClient-40]-[INFO] 线程3生成6
2013-04-06 16:18:17 [dingchd.multithread.TestLock-20]-[INFO] 线程1传入27
2013-04-06 16:18:17 [dingchd.multithread.TestLock-22]-[INFO] 线程1获取27
2013-04-06 16:18:17 [dingchd.multithread.TestClient-40]-[INFO] 线程1生成7
2013-04-06 16:18:17 [dingchd.multithread.TestLock-20]-[INFO] 线程1传入7
2013-04-06 16:18:17 [dingchd.multithread.TestLock-22]-[INFO] 线程1获取7
传入和获取是同步的,加锁了

注:此处的Lock是static类型的

代码改为如下也启动同步作用:

public static synchronized void inc(long cur,int id){
//lock.lock();
user.cur = cur;
log.info("线程"+ id +"传入"+ cur);

log.info("线程"+ id + "获取"+ user.cur);
//lock.unlock();
}



代码改为如下也可以:

public class TestLock {
private static Lock lock = new ReentrantLock();
private static Object obj = new Object();
private int id;
private static User user = new User();
private static Log log = LogFactory.getLog(TestLock.class);
TestLock(int id){
this.id = id;
}
public void inc(long cur,int id){
//lock.lock();
synchronized(obj){
user.cur = cur;
log.info("线程"+ id +"传入"+ cur);

log.info("线程"+ id + "获取"+ user.cur);
}
//lock.unlock();
}
}



区别:lock相比synchronized更高效,需手动释放,一个隐式一个显式,一个关键字一个类库方法

数据如下:(http://itcxy.com/base/jprove/2012/1221/459.html)
Threads 1x
synch 1x
Lock 1x
AtomicInteger 2x
synch 2x
Lock 2x
AtomicInteger
1 1.797 2.175 0.947 3.246 4.111 1.703
2 8.685 4.134 1.889 13.144 4.901 1.949
4 7.942 3.040 1.735 13.182 4.960 1.945
8 7.648 3.011 1.894 13.287 4.979 1.951
16 8.017 2.974 1.735 13.040 4.573 1.950
32 7.908 2.958 1.777 13.059 4.845 1.958
64 7.853 2.972 1.878 13.316 5.004 1.954
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值