同步操作将从 电霸儿/grain 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
1、grain-thread(系统多线程模型)。依赖:grain-log
2、grain-threadmsg(系统多线程模型,线程消息通讯)。依赖:grain-thread,grain-msg
3、grain-rpc(远程对象访问)。依赖:grain-threadmsg,grain-tcp
4、grain-distributedlock(多对多关系的分布式锁)。依赖:grain-rpc
5、grain-threadwebsocket(websocket服务器,使用系统多线程模型处理业务)。依赖:grain-websocket-lib,grain-threadmsg
6、grain-httpserver(基于servlet的http服务器)。依赖:grain-log
7、grain-threadkeylock(支持锁类型单键值与双键值的多线程锁)。依赖:grain-log
https://github.com/dianbaer/grain
https://gitee.com/dianbaer/grain
grain最核心的组件,支撑起上层很多组件包含threadmsg(线程消息通讯)、
rpc(远程对象访问)、distributedlock(多对多关系的分布式锁)、threadwebsocket(websocket服务器)。
grain-thread支持创建多线程池,业务轮询精准注入指定线程ID,任意消息(例如:msg、tcp、websocket等)精准注入指定线程ID。
系统多线程之间的通讯,业务线程跳转都依赖此组件。
通过grain-rpc可以创建RPC客户端与服务器进行远程对象访问。多线程阻塞,唤醒等复杂的多线程业务都已内部解决。
RPC客户端
RPC服务器
简单例子:
1、创建消息包
RPCTestC.Builder builder = RPCTestC.newBuilder();
builder.setName("RPC你好啊");
TcpPacket pt = new TcpPacket(TestTCode.TEST_RPC_C, builder.build());
2、远程调用
TcpPacket ptReturn = WaitLockManager.lock(session, pt);
例子(包含RPC客户端与RPC服务器,直接运行main函数即可):
去中心化思路,通过grain-distributedlock可以创建分布式锁服务器与锁客户端。
grain-distributedlock不同类型互不影响,相同类型不同键值互不影响。仅仅当类型与键值都相等时会进行分布式阻塞。
锁客户端与锁服务器的双向线程阻塞,服务器匹配、类型键值与线程ID的匹配都已内部解决。
锁客户端
锁服务器
简单例子:
// 获取锁
int lockId = DistributedLockClient.getLock("111", "user");
if (lockId == 0) {
return;
}
/*********** 执行分布式锁业务逻辑 *********/
System.out.println("分布式锁id为:" + lockId);
/*********** 执行分布式锁业务逻辑 *********/
// 释放锁
DistributedLockClient.unLock("111", "user", lockId);
例子(包含分布式锁客户端与服务器,直接运行main函数即可):
grain-distributedlock-clienttest
grain-distributedlock-servertest
将grain-threadwebsocket包引入web工程,可以创建websocket服务器。
(业务分发至系统多线程模型grain-thread,可以精准指派某业务归属线程ID)
public class TestWSService implements IWSListener {
@Override
public Map<String, String> getWSs() throws Exception {
HashMap<String, String> map = new HashMap<>();
map.put("testc", "onTestC");
return map;
}
public void onTestC(WsPacket wsPacket) throws IOException, EncodeException {
TestC testc = (TestC) wsPacket.getData();
wsPacket.putMonitor("接到客户端发来的消息:" + testc.getMsg());
TestS.Builder tests = TestS.newBuilder();
tests.setWsOpCode("tests");
tests.setMsg("你好客户端,我是服务器");
WsPacket pt = new WsPacket("tests", tests.build());
Session session = (Session) wsPacket.session;
session.getBasicRemote().sendObject(pt);
}
}
例子(该例子内部含有js websocket客户端,使用tomcat启动即可):
定义关键字并统筹所有请求参数,进行数据格式化。支持文件与操作数据的隔离。
支持post表单数据与json数据,支持表单文件,支持get拼接参数,支持扩展消息包过滤器,支持扩展请求回复类型。
public class TestHttpService implements IHttpListener {
@Override
public Map<String, String> getHttps() {
HashMap<String, String> map = new HashMap<>();
map.put("1", "onTestC");//返回json
map.put("2", "onFileC");//返回文件
map.put("3", "onImageC");//返回图片
map.put("4", "onStringC");//返回字符串
map.put("5", "onReplyStringC");//返回自定义头消息字符串
map.put("6", "onException");//异常返回
return map;
}
public HttpPacket onTestC(HttpPacket httpPacket) throws IOException, EncodeException {
GetTokenS.Builder builder = GetTokenS.newBuilder();
builder.setHOpCode(httpPacket.gethOpCode());
builder.setTokenId("111111");
builder.setTokenExpireTime("222222");
HttpPacket packet = new HttpPacket(httpPacket.gethOpCode(), builder.build());
return packet;
}
public ReplyFile onFileC(HttpPacket httpPacket) throws IOException, EncodeException {
File file = new File(HttpConfig.PROJECT_PATH + "/" + HttpConfig.PROJECT_NAME + "/k_nearest_neighbors.png");
ReplyFile replyFile = new ReplyFile(file, "你好.png");
return replyFile;
}
public ReplyImage onImageC(HttpPacket httpPacket) throws IOException, EncodeException {
File file = new File(HttpConfig.PROJECT_PATH + "/" + HttpConfig.PROJECT_NAME + "/k_nearest_neighbors.png");
ReplyImage image = new ReplyImage(file);
return image;
}
public String onStringC(HttpPacket httpPacket) throws IOException, EncodeException {
return "<html><head></head><body><h1>xxxxxxxxxxxx<h1></body></html>";
}
public ReplyString onReplyStringC(HttpPacket httpPacket) throws IOException, EncodeException {
String str = "<html><head></head><body><h1>xxxxxxxxxxxx<h1></body></html>";
ReplyString replyString = new ReplyString(str, "text/html");
return replyString;
}
public void onException(HttpPacket httpPacket) throws HttpException {
GetTokenS.Builder builder = GetTokenS.newBuilder();
builder.setHOpCode("0");
builder.setTokenId("111111");
builder.setTokenExpireTime("222222");
throw new HttpException("0", builder.build());
}
}
例子(该例子内部含有js http客户端,使用tomcat启动即可):
在多线程业务中,支持锁类型的单键值与双键值,并且支持锁函数
简单例子1(锁函数):当类型为TEST1,键值为111同时调用函数时,会进行锁定。
public String lockFunction(Object... params) {}
String str = (String) KeyLockManager.lockMethod("111", TEST1, (params) -> lockFunction(params), new Object[] { "222", 111 });
简单例子2(锁函数):当类型为TEST1,键值为111或222同时调用函数时,会进行锁定。
String str = (String) KeyLockManager.lockMethod("111", "222", TEST1, (params) -> lockFunction(params), new Object[] { "222", 111 });
ant
java8
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。