多线程发送消息之流控

近期接触到流量,由于旧的版本流控不准确,所以相对其改进一下

整体方案:使用jdk1.5的信号量机制,没法送一条消息,信号量加1,当信号量达到上限时,阻塞,等待定时线程来清理(每100毫秒尝试清理一次)

1.首先想到使用Semaphore来实现,不过测试时发现,由于semaphore不能够重入,这导致,在1秒钟内一个线程发送了一条之后,就会阻塞,这样一秒钟每个线程只能发送一条消息。

2.采用ArrayBlockingQueue来实现,每发送一条调用一次put方法(put时如果发现超过1秒钟,则立即清0),定时线程每100毫秒尝试清理一次,但是发现用ArrayBlockingQueue似乎不够轻便,因为其内部维护了一个对象数组。

3.自定义个可重入的信号量类,参照ArrayBlockingQueue来实现,去掉其中的对象数组,值保留put和clear方法,(put方法改名为acquire)。


public class ReentrantSemaphore
{
private int size;
private final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
private int count;

public ReentrantSemaphore(int capacity) {
size = capacity;
lock = new ReentrantLock();
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}


public void clear() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
count = 0;
notFull.signalAll();
} finally {
lock.unlock();
}
}

public void acquire(int x) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == size)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
count+=x;
} finally {
lock.unlock();
}
}
}


经过测试,这种方式可以比较好的实现,如果其他人有更好的实现,希望能一起讨论。

完整代码在附件中:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Eclipse Paho Java 客户端库来实现Java多线程通过MQTT发送消息的功能。以下是一个简单的示例代码: ```java import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; public class MqttThread extends Thread { private String topic; private String content; private MqttClient client; public MqttThread(String topic, String content) { this.topic = topic; this.content = content; } @Override public void run() { String broker = "tcp://localhost:1883"; String clientId = "JavaThreadClient"; MemoryPersistence persistence = new MemoryPersistence(); try { client = new MqttClient(broker, clientId, persistence); client.connect(); MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(2); client.publish(topic, message); client.disconnect(); } catch (MqttException e) { e.printStackTrace(); } } } ``` 在这个示例中,我们创建了一个 `MqttThread` 类,它包含了要发送消息的主题和内容。当我们调用 `start()` 方法时,它会连接到本地 MQTT 代理,并将消息发布到指定的主题。请注意,这个示例中使用了 QoS 为 2 的消息发布。 可以通过以下方式来使用这个示例: ```java MqttThread thread1 = new MqttThread("topic1", "message1"); MqttThread thread2 = new MqttThread("topic2", "message2"); thread1.start(); thread2.start(); ``` 这里我们创建了两个 `MqttThread` 实例,并将它们分别启动,从而实现了多线程发送 MQTT 消息的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值