java并发库Semaphore问题?

congjunhai 2016-08-17 11:29:50
两个线程进入Semaphore,如下:
semp.acquire();
System.out.println("Accessing ");
semp.release();
请问,有没有可能打印AcceAccessing ssing ,也就是说进入信号量中的线程是互斥的吗?
...全文
234 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewMoons 2016-08-17
  • 打赏
  • 举报
回复
你的代码里没有synchronized或者相关的锁机制代码,自然就没有你说的互斥嘛,说到底你还是不理解synchronized的意义。 多线程是否会互斥其实也就是是否需要同步,取决于下面2个需求 1、这些线程是否会访问共享资源 2、是否要保证共享资源访问的顺序(类似一张票不能卖2次) 不要一看见多线程就一定就是会有synchronized,这根本是2个东西。多线程只是提高代码执行效率,充分利用cpu等硬件资源,只有你的需要需要同步,才去人为的写synchronized代码,取决于需求!不要形而上学。
congjunhai 2016-08-17
  • 打赏
  • 举报
回复
明白了,谢谢二楼回答。也就是会出现AcceAccessingssing这种结果,我测试了很多遍,没有出现上诉情况,我怀疑是不是semaphore自带锁机制。 package com.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class Semaphore1 { public static void main(String[] args) { // 线程池 ExecutorService exec = Executors.newCachedThreadPool(); // 只能5个线程同时访问 final Semaphore semp = new Semaphore(5); // 模拟20个客户端访问 for (int index = 0; index < 20; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { // 获取许可 semp.acquire(); System.out.println("Accessing: " + NO); Thread.sleep(1000); // 访问完后,释放 semp.release(); System.out.println("-----------------"+semp.availablePermits()); } catch (InterruptedException e) { e.printStackTrace(); } } }; exec.execute(run); } // 退出线程池 exec.shutdown(); } } 这是测试代码。 每次打印都是 Accessing: 0 Accessing: 1 …… 这种可见他们内部并没有征厕所,当然可能是重现不出来。
NewMoons 2016-08-17
  • 打赏
  • 举报
回复
引用 2 楼 congjunhai 的回复:
2楼不是我的学习方法有问题,可能我没描述明白,我知道Semaphore是控制线程个数的,而且5个厕所坑也很经典,我想问的是,5个线程在享用这5个厕所的时候会不会存在竞争关系,也就是说在一个打印Accessing(蹲坑)的时候,另外一个会不会和他抢(在第一个没打印完,强行自己打印)
前面已经说了你这个问题另外一个问题,也就是说和Semaphore没有关系。你把两者关联在一起没有意义,只能误导看问题的人。 多线程是否会互斥其实也就是是否需要同步,取决于下面2个需求 1、这些线程是否会访问共享资源 2、是否要保证共享资源访问的顺序(类似一张票不能卖2次) 如果你没有上面2个需求,大家各运行各的,不存在互斥即同步问题。就好像5个窗口同时卖火车票,如果事先约定每个窗口卖的票都不会重复(比如每个窗口卖的是不同的线路),你同步干嘛???如果每个窗口卖的有相同线路的票,那就要保证如果2个窗口同时卖票时不能把一张票卖2次,这时才需要同步,即使用synchronized锁住卖票那段代码。保证一个窗口在卖票的时候加锁,当另一个窗口也想卖票时,synchronized锁会告诉这个窗口,嘿!我正卖着呢,等我卖完了你再卖!当然,如果把所有票都锁住也不合理,实际场景肯定有分而治之锁的策略,这里就不深入讨论了。 回到厕所的问题,Semaphore保证只能5个人进厕所,但厕所的蹲坑未必就是5个,也可能是3个,那这5个人就要继续竞争这个3个坑,Semaphore只保证放进厕所5个人,但是否保证这5个人一定同时能有蹲坑就不是它的事了。就要靠synchronized来保证3个蹲坑的资源同步了,否则就会有人打架争蹲坑,而这没有Semaphore的一点责任,而是synchronized的责任。
congjunhai 2016-08-17
  • 打赏
  • 举报
回复
2楼不是我的学习方法有问题,可能我没描述明白,我知道Semaphore是控制线程个数的,而且5个厕所坑也很经典,我想问的是,5个线程在享用这5个厕所的时候会不会存在竞争关系,也就是说在一个打印Accessing(蹲坑)的时候,另外一个会不会和他抢(在第一个没打印完,强行自己打印)
NewMoons 2016-08-17
  • 打赏
  • 举报
回复
楼主,请先解释下什么叫线程互斥,不明白你想问什么。Semaphore应该和你所谓的线程互斥没任何关系,它解决的问题就是保证了同一时间能运行的最大线程数。至于线程之间有什么通信和Semaphore无关也没必要关心。 引用一下网上的一段话:Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。 生产者和消费者模型的概念你完全没搞懂。它本身就是针对多生产者和多消费者的,一个的话没有任何意义。synchronized只是保证了多线程情况下保证每个共享资源能被同步安全地访问(比如保证每张火车票不被卖2次)。而不是说只能有一个线程可以访问。 我觉得楼主的学习方法有问题,你要搞清楚某项技术,首先要弄明白这个技术实现的目的是什么,自己先百度了解一下。有了具体疑问再针对性地提问。你的问题显得你学东西太盲目了。

62,612

社区成员

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

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