package com.boce.gbkutf;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.ibm.icu.util.Calendar;
//实现多key值多锁,如 key=12,已经加锁(HashMap 中存在),其它线程就不可以对key=12,进行操作,线程阻塞,需要等当前线程操作完成后,其它线程才可以操作.
package com.boce.gbkutf;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.ibm.icu.util.Calendar;
public class MutiLock {
final Lock lock = new ReentrantLock();//锁对象
final Condition notFull = lock.newCondition();//写线程条件
final Condition notEmpty = lock.newCondition();//读线程条件
//lock数量
final Map<String,String> items = new HashMap<String,String>(100);//缓存队列
//锁定某个商品id
public void put(String x) throws InterruptedException {
lock.tryLock(1000L, TimeUnit.SECONDS); //锁定6秒钟
try {
while (x == items.get(x)){//如果已经存在对象
notFull.await();//阻塞写线程
System.out.println("time:"+Calendar.getInstance().getTimeInMillis());
}
items.put(x, x);//赋值
System.out.println("put:"+x);
} finally {
lock.unlock();
}
}
//释放某个锁定的商品id
public void take(String key) throws InterruptedException {
lock.tryLock(1000L, TimeUnit.SECONDS);
try {
notFull.signal();//唤醒写线程
items.remove(key);
System.out.println("================get:"+key);
} finally {
lock.unlock();
}
}
}
//测试类
package com.boce.gbkutf;
import java.util.Random;
public class ThreadTest implements Runnable{
private String key;
private MutiLock mutiLock;
public ThreadTest(String key, MutiLock mutiLock) {
super();
this.key = key;
this.mutiLock = mutiLock;
}
@Override
public void run() {
try {
mutiLock.put(key);
Random rand = new Random();
int data = rand.nextInt(2000);
System.out.println("key:"+key+";工作时间:"+data);
//模拟工作时长
Thread.sleep(data);
mutiLock.take(key);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.boce.gbkutf;
public class TestMain {
public static void main(String[] args) {
MutiLock mutiLock = new MutiLock();
for (int i = 0; i < 2; i++) {
String key = "123456";
ThreadTest test = new ThreadTest(key, mutiLock);
Thread test1 = new Thread(test);
test1.start();
String key1 = "123456"+i;
ThreadTest test11 = new ThreadTest(key1, mutiLock);
Thread test12 = new Thread(test11);
test12.start();
}
}
}
测试日志:
put:123456
put:1234561
key:123456;工作时间:660
put:1234560
key:1234561;工作时间:795
key:1234560;工作时间:1090
================get:123456
time:1489373212371
put:123456
key:123456;工作时间:419
================get:1234561
================get:1234560
================get:123456
相关推荐
GiliSoft USB Lock能够给电脑的USB端口添加保护,未经许可即使你将U盘或其他USB设备插入到USB商品上也无法使用,支持各种USB移动设备,可阻止所有这类不属于你的驱动器和设备,无需担心数据被别人窃取。...
秒杀系统是电商领域常见的一种高并发场景,用于在短时间内处理大量用户对限量商品的抢购请求。在设计这样的系统时,分布式锁是一种关键的技术手段,用于保证在高并发环境下的数据一致性与业务正确性。这个名为...
项目中的"07_12_Test3_lock"可能是一个包含测试代码的类或文件,它可能展示了如何使用Lock实现生产者-消费者的模型。这个类可能会包含以下组件: 1. **缓冲区**:一个固定大小的数据结构,存储生产者生产的商品和...
在常见的并发更新操作中,如商品减库存和消息队列的生产和消费,需要通过加锁来保证数据不会因为并发访问而出现错误。 #### 锁的持有周期 锁的生命周期通常在事务开始时获得,并在事务提交或回滚时释放。这一点与...
在Python编程中,分布式锁是一种在分布式系统中用于协调不同节点间访问共享资源的重要机制。在上述场景中,我们讨论的是分布式系统中的并发问题,尤其是秒杀活动这种高并发操作,如果不加以控制,可能会导致数据一致...
`RedissonMultiLock` 的实现原理相当直观,它实际上是对多个 `RedissonLock` 对象的封装,通过循环调用每个锁的加锁和释放方法来实现连锁效果。 在提供的代码示例中,我们可以看到如何创建并使用 `...
若仅在应用层面上实现加锁机制,则无法有效防止外部系统或其他应用程序对数据的修改。 #### 二、悲观锁在MySQL中的实现 MySQL的InnoDB存储引擎支持多种类型的锁,其中最常用的就是悲观锁的实现方式之一——行级锁...
2. SQL查询中,要统计各类商品的数量,应该使用GROUP BY子句对类型进行分组,并使用COUNT()函数计算每种类别的数量。正确的SQL语句是A选项,它将返回每个类型及其对应的商品数量。 3. 数据库设计的原则包括“一事一...
- **加锁**:当线程需要对某商品执行秒杀操作时,首先尝试获取对应的锁(通过`SETNX`命令)。如果获取成功,则继续执行秒杀逻辑;否则,等待一段时间后重试。 - **执行业务逻辑**:在获取锁后,执行秒杀逻辑(如减少...
例如,当我们使用`synchronized`关键字加锁,并在其中调用`wait()`方法时,如果没有正确处理这种异常情况,就可能导致程序逻辑混乱。 #### 二、虚假唤醒的代码示例解析 为了更好地理解虚假唤醒这一概念,下面将...
4. 加锁与解锁:在秒杀业务逻辑前,先调用 `lock.lock()` 方法获取锁,确保其他线程无法同时执行。完成业务逻辑后,使用 `unlock()` 方法释放锁: ```java try { lock.lock(); // 秒杀逻辑,例如减少库存 } ...
例如,在电商系统中,如果商品库存按类别划分,可以对每个类别的库存使用一个分段锁,这样在查询和更新不同类别库存时,可以减少锁冲突,提高系统吞吐量。 实现分段锁可以结合Redis的哈希数据结构,为每个段分配一...
不同点在于,Lock提供了更细粒度的控制,如可重入、尝试加锁、可中断等待等,且必须手动释放锁。 12. 关系数据库使用二维表来表示实体间的联系,这是关系模型的基础。 13. Java源文件的第一条语句应是package声明...
本文实例讲述了PHP使用文件锁解决高并发问题。...//查询商品数量是否大于0,大于0才能下单,并减少库存 $fp = fopen("lock.txt", "r"); //加锁 if(flock($fp,LOCK_EX)) { $res=mysqli_fetch_assoc(mysq
- **抢购活动**:在高并发抢购活动中,为了防止商品超卖,可以使用Redis分布式锁来确保商品库存的准确性。 - **数据同步**:在分布式系统中,多个服务可能需要更新同一份数据,使用Redis分布式锁可以确保数据的一致...
- 在示例中,`Num` 类的 `add` 方法使用 `lock.acquire()` 加锁,确保在同一时刻只有一个线程能执行加法操作。执行完操作后,通过 `lock.release()` 解锁,让其他线程有机会获取锁并执行。 - 使用锁可以避免多个...
在Linux系统中,可以通过`flock()`函数对文件加锁,确保同一时间只有一个进程可以访问特定文件。以下是一个使用文件锁处理并发的例子: ```php $http = new swoole_http_server("0.0.0.0", 9510); $http->set(array...
如上例所示,通过使用`threading.RLock`代替`threading.Lock`,可以在同一个线程内多次获取锁,而不必担心死锁的问题。 #### 六、死锁 死锁是多线程程序中的一种极端情况,它发生在两个或多个线程相互等待对方持有...