如何让Java以光的速度跨线程通信

如何让Java以光的速度跨线程通信,第1张

一个比Disruptor吞吐量等性能指标更好的框架,使用Railway算法,将线程之间的消费发送参考现实生活中火车在站点之间搬运货物。
目标起始于一个简单的想法:创建一个开发人员友好的,简单的,轻量级线程间的通信框架,无需使用任何锁,同步器,信号量,等待,通知以及没有队列,消息,事件或任何其它并发特定的语法或工具。
只是一个Java接口接受到POJO以后在其背后实现这个通信,这个主意很类似Akka的Actors,但是它也许是有点矫枉过正,特别是对于单个多核计算机上线程间的通信优化必须是轻量的。
Akka的伟大之处是跨进程通信,特别是Actor是能够跨越不同JVM节点实现分布式通信。
无论如何,你可能觉得使用Akka在一个小型项目上有些过度,因为你只需要线程之间的通信,但是你还是想使用类似Actor这种做法模式。
该文章作者使用了动态代理 堵塞队列和一个缓存的线程池创建了这个解决方案,如图:
SPSC队列是一个Single Producer/Single Consumer 队列(单生产者/单消费者),而MPSC是一个Multi Producer/Single Consumer队列。
Dispatcher线程从Actor线程接受到消息,然后发送到相应的SPSC中。
Actor线程从接受的消息中使用数据,调用相应的actor类的方法,Actor实例都是发送消息给MPSC队列,然后再从Actor线程那里得到消息。
下面是ping-pong案例:
public interface PlayerA (
void pong(long ball); //send and forget method call
}
public interface PlayerB {
void ping(PlayerA playerA, long ball); //send and forget method call
}
public class PlayerAImpl implements PlayerA {
@Override
@ublic void pong(long ball) {
}
}
public class PlayerBImpl implements PlayerB {
@Override
public void ping(PlayerA playerA, long ball) {
playerApong(ball);
}
}
public class PingPongExample {
public void testPingPong() {
// this manager hides the complexity of inter-thread communications
// and it takes control over actor proxies, actor implementations and threads
ActorManager manager = new ActorManager();
// registers actor implementations inside the manager
managerregisterImpl(PlayerAImplclass);
managerregisterImpl(PlayerBImplclass);
//Create actor proxies Proxies convert method calls into internal messages
//which would be sent between threads to a specific actor instance
PlayerA playerA = managercreateActor(PlayerAclass);
PlayerB playerB = managercreateActor(PlayerBclass);
for(int i = 0; i < 1000000; i++) {
playerBping(playerA, i);
}
}
这两个play能够每秒打500,000个乒乓。但是如果和单个线程执行速度相比,还是很差的,同样代码在单个线程可以到达每秒两百万个。
作者开始研究缓慢的原因,在一些校验和测试以后,他认为是Actors之间发送消息影响了整体性能:
作者找到一个SPSC单生产者和单消费者的无锁队列,>#include <stdioh>
int main(int argc, char argv){
CreateThread(NULL, 0, thread2, this, 0, 0);
printf("主线程正在执行!\n");
return 0;
}
void thread2(){
sleep(2);//睡2毫秒
printf("第二个线程在运行!\n");
}
这个例子可能很简单,但能说明问题了。

线程间通信就是通过全局变量啊,线程之间没有“通信”的说法吧,不管有几个线程,它们都是在同一个进程地址空间内,都共享同样的内存空间,所以“通信”的说法才多见于进程之间,因为不同的进程才是不同的内存地址空间。进程内的变量每个线程都是可以访问的,是共享的,但是线程之间没有固定的执行顺序,为避免时序上的不同步问题,所以线程之间才会需要同步机制。线程之间的重点就是同步机制。

用Activity对象的runOnUiThread方法更新,在子线程中通过runOnUiThread()方法更新UI,强烈推荐使用。

这种方法更简单,但需要传递要更新的View过去,推荐使用


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/13342558.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-31
下一篇2025-08-31

发表评论

登录后才能评论

评论列表(0条)

    保存