两个线程进入Semaphore,如下:
semp.acquire();
System.out.println("Accessing ");
semp.release();
请问,有没有可能打印AcceAccessing ssing ,也就是说进入信号量中的线程是互斥的吗?
semp.acquire();
System.out.println("Accessing ");
semp.release();
请问,有没有可能打印AcceAccessing ssing ,也就是说进入信号量中的线程是互斥的吗?
引用一下网上的一段话:Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。生产者和消费者模型的概念你完全没搞懂。它本身就是针对多生产者和多消费者的,一个的话没有任何意义。synchronized只是保证了多线程情况下保证每个共享资源能被同步安全地访问(比如保证每张火车票不被卖2次)。而不是说只能有一个线程可以访问。我觉得楼主的学习方法有问题,你要搞清楚某项技术,首先要弄明白这个技术实现的目的是什么,自己先百度了解一下。有了具体疑问再针对性地提问。你的问题显得你学东西太盲目了。
前面已经说了你这个问题另外一个问题,也就是说和Semaphore没有关系。你把两者关联在一起没有意义,只能误导看问题的人。多线程是否会互斥其实也就是是否需要同步,取决于下面2个需求
1、这些线程是否会访问共享资源
2、是否要保证共享资源访问的顺序(类似一张票不能卖2次)
如果你没有上面2个需求,大家各运行各的,不存在互斥即同步问题。就好像5个窗口同时卖火车票,如果事先约定每个窗口卖的票都不会重复(比如每个窗口卖的是不同的线路),你同步干嘛???如果每个窗口卖的有相同线路的票,那就要保证如果2个窗口同时卖票时不能把一张票卖2次,这时才需要同步,即使用synchronized锁住卖票那段代码。保证一个窗口在卖票的时候加锁,当另一个窗口也想卖票时,synchronized锁会告诉这个窗口,嘿!我正卖着呢,等我卖完了你再卖!当然,如果把所有票都锁住也不合理,实际场景肯定有分而治之锁的策略,这里就不深入讨论了。回到厕所的问题,Semaphore保证只能5个人进厕所,但厕所的蹲坑未必就是5个,也可能是3个,那这5个人就要继续竞争这个3个坑,Semaphore只保证放进厕所5个人,但是否保证这5个人一定同时能有蹲坑就不是它的事了。就要靠synchronized来保证3个蹲坑的资源同步了,否则就会有人打架争蹲坑,而这没有Semaphore的一点责任,而是synchronized的责任。
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
……
这种可见他们内部并没有征厕所,当然可能是重现不出来。
多线程是否会互斥其实也就是是否需要同步,取决于下面2个需求
1、这些线程是否会访问共享资源
2、是否要保证共享资源访问的顺序(类似一张票不能卖2次)不要一看见多线程就一定就是会有synchronized,这根本是2个东西。多线程只是提高代码执行效率,充分利用cpu等硬件资源,只有你的需要需要同步,才去人为的写synchronized代码,取决于需求!不要形而上学。