java如何效率的解决这个抢房间座位问题

abcbuzhiming 2014-03-19 09:12:53
假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量的人等待空位,房间内的人可能随时离开,因此要不停的扫描房间空位一旦有空的就抢座上去。

目前的难点,首先要保证线程同步,不能一个座位放上去两个人,其次就是要保证速度,线程同步要加锁,加锁就影响效率。

我目前考虑的方法是用hashmap代表一个房间的5个位置,但是这样检查空位和坐上去这两个动作都要加锁,感觉效率很低,10个房间还好说,1000个房间呢
...全文
368 12 打赏 收藏 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ok350350 2014-03-19
  • 打赏
  • 举报
回复
引用 4 楼 abcbuzhiming 的回复:
[quote=引用 2 楼 rumlee 的回复:] 加锁确实对性能有影响,但是这是不可避免的。 这种问题为什么要循环扫描呢?座位上的人离开的时候,不主动通知吗?
请教如何实现这个通知模型?用什么方式[/quote] 你可以参考一下observer的模式,java已经提供了代码实现。
致知Fighting 2014-03-19
  • 打赏
  • 举报
回复
引用 8 楼 abcbuzhiming 的回复:
[quote=引用 6 楼 ygycomon 的回复:] 你实测过加锁带来的性能开销么? 别老妄想一些“多快好省”的方法可以解决问题,在你的业务场景里,如果要多线程的“抢座”,就必须要上锁,同步抢座,离开(insert、remove)的操作,这是没有办法绕过的步骤,所以不管加锁开销多大,要么你就接受这个开销,要么就接受数据安全问题 这个加锁的过程你想复杂了,可以用concurrenthashmap来做
我是考虑过用concurrenthashmap来做这个东西,但是仍然存在一个问题,concurrenthashmap只是保证自身操作的那些方法是线程安全的,但是在实际使用时,我首先必须检查concurrenthashmap的一个key(座位)上是不是空的,然后再往里面放人,这是两步操作,于是我必须在concurrenthashmap外面再加一次锁,在完成后解除锁。锁上加锁是不是很囧[/quote] 锁上加锁没什么好囧的,如果要保证安全,你就要设计合理的数据结构,如果你设计出来的结构必须要加锁,那是跑不掉的。 不过这个场景如要我来设计,我不会用hashmap这样的数据结构,会转用其他的思路来解决问题
abcbuzhiming 2014-03-19
  • 打赏
  • 举报
回复
引用 6 楼 ygycomon 的回复:
你实测过加锁带来的性能开销么? 别老妄想一些“多快好省”的方法可以解决问题,在你的业务场景里,如果要多线程的“抢座”,就必须要上锁,同步抢座,离开(insert、remove)的操作,这是没有办法绕过的步骤,所以不管加锁开销多大,要么你就接受这个开销,要么就接受数据安全问题 这个加锁的过程你想复杂了,可以用concurrenthashmap来做
我是考虑过用concurrenthashmap来做这个东西,但是仍然存在一个问题,concurrenthashmap只是保证自身操作的那些方法是线程安全的,但是在实际使用时,我首先必须检查concurrenthashmap的一个key(座位)上是不是空的,然后再往里面放人,这是两步操作,于是我必须在concurrenthashmap外面再加一次锁,在完成后解除锁。锁上加锁是不是很囧
致知Fighting 2014-03-19
  • 打赏
  • 举报
回复
100个1000个元素加锁控制其实是小意思,你要自己实现的话,可以学习concurrenthashmap里的方法,“分段加锁”,把1000个对象分成10个锁来管理。其实这么少的元素对性能没有什么太大的影响 当你的加锁单元多到10w个100w个的时候,可以做一些逻辑上的控制,比如给排队的人编个号标个区,上半区的人只能去前面的房间,即使后面的房间有位置也不许他们坐,这样就把问题简化成为少量加锁单元的场景
致知Fighting 2014-03-19
  • 打赏
  • 举报
回复
你实测过加锁带来的性能开销么? 别老妄想一些“多快好省”的方法可以解决问题,在你的业务场景里,如果要多线程的“抢座”,就必须要上锁,同步抢座,离开(insert、remove)的操作,这是没有办法绕过的步骤,所以不管加锁开销多大,要么你就接受这个开销,要么就接受数据安全问题 这个加锁的过程你想复杂了,可以用concurrenthashmap来做
abcbuzhiming 2014-03-19
  • 打赏
  • 举报
回复
引用 1 楼 duxingzhe0311 的回复:
java.util.concurrent.ExecutorService java.util.concurrent.Executors java.util.concurrent.Semaphore 能搞定不?
这和我说的加锁没啥不同啊,线程同步无论用什么方法都要耗费大量的资源
abcbuzhiming 2014-03-19
  • 打赏
  • 举报
回复
引用 2 楼 rumlee 的回复:
加锁确实对性能有影响,但是这是不可避免的。 这种问题为什么要循环扫描呢?座位上的人离开的时候,不主动通知吗?
请教如何实现这个通知模型?用什么方式
rumlee 2014-03-19
  • 打赏
  • 举报
回复
引用 2 楼 rumlee 的回复:
加锁确实对性能有影响,但是这是不可避免的。 这种问题为什么要循环扫描呢?座位上的人离开的时候,不主动通知吗?
加锁你都考虑性能问题,可你想过没有,这个问题真正的性能瓶颈在于循环扫描上。 如果能够改成座位上的人离开的时候,主动通知的话,那性能将大大提升。
rumlee 2014-03-19
  • 打赏
  • 举报
回复
加锁确实对性能有影响,但是这是不可避免的。 这种问题为什么要循环扫描呢?座位上的人离开的时候,不主动通知吗?
rockets311 2014-03-19
  • 打赏
  • 举报
回复
java.util.concurrent.ExecutorService java.util.concurrent.Executors java.util.concurrent.Semaphore 能搞定不?
致知Fighting 2014-03-19
  • 打赏
  • 举报
回复
引用 11 楼 abcbuzhiming 的回复:
[quote=引用 9 楼 ygycomon 的回复:] 锁上加锁没什么好囧的,如果要保证安全,你就要设计合理的数据结构,如果你设计出来的结构必须要加锁,那是跑不掉的。 不过这个场景如要我来设计,我不会用hashmap这样的数据结构,会转用其他的思路来解决问题
请教你的思路谢谢[/quote] 做一个阻塞队列维护一个唯一的token队列就好了,每个token对应一个座位,这样你的场景就简化成为简单的 生产者-消费者 场景了
abcbuzhiming 2014-03-19
  • 打赏
  • 举报
回复
引用 9 楼 ygycomon 的回复:
锁上加锁没什么好囧的,如果要保证安全,你就要设计合理的数据结构,如果你设计出来的结构必须要加锁,那是跑不掉的。 不过这个场景如要我来设计,我不会用hashmap这样的数据结构,会转用其他的思路来解决问题
请教你的思路谢谢

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧