我使用信号量,我希望当列表大小为零时,线程等待其他线程,但为什么信号量不停止执行?信号量不是像notify和wait一样工作吗?
结果:add remove add Exception in thread“Thread-2”java.lang.IndexOutOfBoundsException:Index:0,Size:0
ArrayList<String> list = new ArrayList<>();
Semaphore semaphore = new Semaphore(0);
new Producer(list, semaphore).start();
new Producer(list, semaphore).start();
new Customeer(list, semaphore).start();
new Customeer(list, semaphore).start();
//////////
static class Customeer extends Thread {
private List<String> list;
private Semaphore semaphore;
public Customeer(List<String> list, Semaphore semaphore) {
this.list = list;
this.semaphore = semaphore;
}
@Override
public void run() {
synchronized (list) {
if (list.size() == 0) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
System.out.println("remove");
}
}
}
static class Producer extends Thread {
private Semaphore semaphore;
private List<String> list;
public Producer(List<String> list, Semaphore semaphore) {
this.list = list;
this.semaphore = semaphore;
}
@Override
public void run() {
synchronized (list) {
list.add("hello");
semaphore.release();
System.out.println("add");
}
}
}
}
您似乎混淆了信号量和同步。当您希望允许n个线程一次访问相同的资源时,就会使用信号量。如果只允许1个线程访问资源,则使用同步时,[n可以是1]。
使用信号量的解决方案
// Java implementation of a producer and consumer
// that use semaphores to control synchronization.
import java.util.concurrent.Semaphore;
class Q {
// an item
int item;
// semCon initialized with 0 permits
// to ensure put() executes first
static Semaphore semCon = new Semaphore(0);
static Semaphore semProd = new Semaphore(1);
// to get an item from buffer
void get()
{
try {
// Before consumer can consume an item,
// it must acquire a permit from semCon
semCon.acquire();
}
catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
// consumer consuming an item
System.out.println("Consumer consumed item : " + item);
// After consumer consumes the item,
// it releases semProd to notify producer
semProd.release();
}
// to put an item in buffer
void put(int item)
{
try {
// Before producer can produce an item,
// it must acquire a permit from semProd
semProd.acquire();
}
catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
// producer producing an item
this.item = item;
System.out.println("Producer produced item : " + item);
// After producer produces the item,
// it releases semCon to notify consumer
semCon.release();
}
}
// Producer class
class Producer implements Runnable {
Q q;
Producer(Q q)
{
this.q = q;
new Thread(this, "Producer").start();
}
public void run()
{
for (int i = 0; i < 5; i++)
// producer put items
q.put(i);
}
}
// Consumer class
class Consumer implements Runnable {
Q q;
Consumer(Q q)
{
this.q = q;
new Thread(this, "Consumer").start();
}
public void run()
{
for (int i = 0; i < 5; i++)
// consumer get items
q.get();
}
}
// Driver class
class PC {
public static void main(String args[])
{
// creating buffer queue
Q q = new Q();
// starting consumer thread
new Consumer(q);
// starting producer thread
new Producer(q);
}
}
使用同步的解决方案
// Java program to implement solution of producer
// consumer problem.
import java.util.LinkedList;
public class Threadexample {
public static void main(String[] args)
throws InterruptedException
{
// Object of a class that has both produce()
// and consume() methods
final PC pc = new PC();
// Create producer thread
Thread t1 = new Thread(new Runnable() {
@Override
public void run()
{
try {
pc.produce();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// Create consumer thread
Thread t2 = new Thread(new Runnable() {
@Override
public void run()
{
try {
pc.consume();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// Start both threads
t1.start();
t2.start();
// t1 finishes before t2
t1.join();
t2.join();
}
// This class has a list, producer (adds items to list
// and consumber (removes items).
public static class PC {
// Create a list shared by producer and consumer
// Size of list is 2.
LinkedList<Integer> list = new LinkedList<>();
int capacity = 2;
// Function called by producer thread
public void produce() throws InterruptedException
{
int value = 0;
while (true) {
synchronized (this)
{
// producer thread waits while list
// is full
while (list.size() == capacity)
wait();
System.out.println("Producer produced-"
+ value);
// to insert the jobs in the list
list.add(value++);
// notifies the consumer thread that
// now it can start consuming
notify();
// makes the working of program easier
// to understand
Thread.sleep(1000);
}
}
}
// Function called by consumer thread
public void consume() throws InterruptedException
{
while (true) {
synchronized (this)
{
// consumer thread waits while list
// is empty
while (list.size() == 0)
wait();
// to retrive the ifrst job in the list
int val = list.removeFirst();
System.out.println("Consumer consumed-"
+ val);
// Wake up producer thread
notify();
// and sleep
Thread.sleep(1000);
}
}
}
}
}
阅读参考资料以获得更清晰的信息
信号量:https://www.geeksforgeeks.org/producer-consumer-solution-using-semaphores-s/
同步:https://www.geeksforgeeks.org/producer-consumer-solution-using-threads-Java/
我有一个ArrayList,它应该在包含0个以上对象时启动报警服务,在包含0个对象时停止报警服务。 这是报警服务类。 这是on Receive方法广播接收器类 问题是,即使调用了报警服务的onDestroy方法,通知也不会停止。 我错过什么了吗? 谢谢
第一个线程组-Wisebuy 1-1在2019-04-30 15:46:11,559开始 我将上升周期设置为1秒,为什么线程组-Wisebuy 1-5891在2019-04-30 15:46:15,541开始? 我将持续时间设置为2秒,为什么线程组-Wisebuy 1-7239在2019-04-30 15:46:18,767停止?
我想在try块中捕获PyCharm的stop信号(当stop被按下时),但是我不知道这个信号是什么或者如何在代码中捕获它。JetBrains在他们的文档中没有提供这方面的见解。 我尝试将其捕获为,但它似乎根本不是异常。 这在编程上是完全可以捕获的吗?
我的代码使用readTextFile读取日志文件,当我在Flink(< code >/opt/Flink-1 . 0 . 3/bin/Flink run-m yarn-cluster-yn 2/home/Flink/Flink-JSON-0.1 . jar )中运行jar时,它成功处理了里面的行,并停止了我的应用程序,而不是等待新的行。我做这件事需要一些参数吗? 先谢谢你了
问题内容: 在我的应用程序中,我想在新用户注册时在某些表中创建条目。例如,我要创建一个用户个人资料,然后将参考他们的公司和一些其他记录。我用post_save信号实现了这一点: 运行时效果很好。我可以使用admin创建一个新用户,其他三个表也可以获取有意义的条目。(除非是雇员,因为保存时未在管理员表单中填写user.first_name和user.last_name。我仍然不明白为什么要这样做)
问题内容: 基本上,一切似乎都可以正常运行并启动,但是由于某些原因,我无法调用任何命令。我已经很轻松地环顾了一个小时,然后看了一些示例/观看视频,但我终生无法找出问题所在。代码如下: 我在中拥有的调试输出实际上可以正常工作并做出响应,并且整个bot都可以运行,没有任何异常,但是它只是不会调用命令。 问题答案: 覆盖提供的默认值将禁止运行任何其他命令。要解决此问题,请在的末尾添加一行。例如: 默认值