Java 我可以从并发线程调用XMPPConnection.sendPacket吗?
动机Java 我可以从并发线程调用XMPPConnection.sendPacket吗?,java,multithreading,concurrency,xmpp,smack,Java,Multithreading,Concurrency,Xmpp,Smack,动机 class XMPPConnection { private boolean connected = false; public boolean isConnected() { return connected; } PacketWriter packetWriter; public void sendPacket( Packet packet ) { if (!isConnected())
class XMPPConnection
{
private boolean connected = false;
public boolean isConnected()
{
return connected;
}
PacketWriter packetWriter;
public void sendPacket( Packet packet )
{
if (!isConnected())
throw new IllegalStateException("Not connected to server.");
if (packet == null)
throw new NullPointerException("Packet is null.");
packetWriter.sendPacket(packet);
}
}
我需要额外的眼睛来确认我能够调用这个方法XMPPConnection.sendPacket(
数据包)同时进行。对于我当前的代码,我以串行方式调用一个可调用列表(最多3个)。每个可调用对象在一个XMPP连接上发送/接收XMPP数据包。我计划通过分离多个线程来并行化这些可调用项&每个可调用项都将在共享XMPPConnection上调用sendpackage,而无需同步
XMPPConnection
class XMPPConnection
{
private boolean connected = false;
public boolean isConnected()
{
return connected;
}
PacketWriter packetWriter;
public void sendPacket( Packet packet )
{
if (!isConnected())
throw new IllegalStateException("Not connected to server.");
if (packet == null)
throw new NullPointerException("Packet is null.");
packetWriter.sendPacket(packet);
}
}
PacketWriter
class PacketWriter
{
public void sendPacket(Packet packet)
{
if (!done) {
// Invoke interceptors for the new packet
// that is about to be sent. Interceptors
// may modify the content of the packet.
processInterceptors(packet);
try {
queue.put(packet);
}
catch (InterruptedException ie) {
ie.printStackTrace();
return;
}
synchronized (queue) {
queue.notifyAll();
}
// Process packet writer listeners. Note that we're
// using the sending thread so it's expected that
// listeners are fast.
processListeners(packet);
}
protected PacketWriter( XMPPConnection connection )
{
this.queue = new ArrayBlockingQueue<Packet>(500, true);
this.connection = connection;
init();
}
}
class PacketWriter
{
公共无效发送包(数据包)
{
如果(!完成){
//为新数据包调用拦截器
//就要发送了,拦截器
//可以修改数据包的内容。
处理器拦截器(数据包);
试一试{
队列放置(数据包);
}
捕获(中断异常ie){
即printStackTrace();
返回;
}
已同步(队列){
queue.notifyAll();
}
//处理数据包编写器侦听器
//使用发送线程,因此
//听众反应很快。
processListeners(数据包);
}
受保护的PacketWriter(XMPPConnection)
{
this.queue=newarrayblockingqueue(500,true);
这个连接=连接;
init();
}
}
我的结论
由于PacketWriter正在使用BlockingQueue,因此我打算从多个线程调用sendPacket没有问题。我说的对吗?您在这里提供的信息不够 我们不知道以下内容是如何实现的:
- 处理器拦截器
- 进程侦听器
- 当PacketWriter仅用于一个方法时,为什么它是XMPPConnection的类成员
- 为什么PacketWriter有一个XMPPConnection成员变量而不使用它
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new ArrayBlockingQueue();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
对于您的使用,您的真正发送者(实际连接的持有者)是消费者,而包准备者/发送者是生产者
另一个有趣的想法是,您可以使用PriorityBlockingQueue来允许闪存覆盖在任何其他等待的数据包之前发送的XMPP数据包
此外,Glen在设计上的观点也是很好的。您可能想看看Smack API(),而不是创建自己的API。是的,您可以从不同的线程发送数据包,而不会出现任何问题 Smack阻塞队列是因为您不能让不同的线程同时写入输出流。Smack负责以每包粒度写入输出流,从而同步输出流 Smack实现的模式只是一个典型的生产者/消费者并发模式。您可能有多个生产者(您的线程),只有一个消费者(Smack的PacketWriter在自己的线程中运行) 问候