iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何解决Java Socket通信技术收发线程互斥的问题
  • 365
分享到

如何解决Java Socket通信技术收发线程互斥的问题

2023-06-17 15:06:36 365人浏览 八月长安
摘要

本篇内容介绍了“如何解决Java Socket通信技术收发线程互斥的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java Socket

本篇内容介绍了“如何解决Java Socket通信技术收发线程互斥的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Java Socket通信技术在很长的时间里都在使用,在不少的程序员眼中都有很多高的评价。那么下面我们就看看如何才能掌握这门复杂的编程语言,希望大家在今后的Java Socket通信技术使用中有所收获。

下面就是Java Socket通信技术在解决收发线程互斥的代码介绍。

  1. package com.bill99.svr;   

  2. import java.io.IOException;   

  3. import java.io.InputStream;   

  4. import java.io.OutputStream;   

  5. import java.net.InetSocketAddress;   

  6. import java.net.Socket;   

  7. import java.net.SocketException;   

  8. import java.net.SocketTimeoutException;   

  9. import java.text.SimpleDateFORMat;   

  10. import java.util.Date;   

  11. import java.util.Properties;   

  12. import java.util.Timer;   

  13. import java.util.TimerTask;   

  14. import java.util.concurrent.ConcurrentHashMap;   

  15. import java.util.concurrent.TimeUnit;   

  16. import java.util.concurrent.locks.Condition;   

  17. import java.util.concurrent.locks.ReentrantLock;   

  18. import org.apache.log4j.Logger;   

  19.  public class SocketConnection {   

  20. private volatile Socket socket;   

  21. private int timeout = 1000*10; //超时时间,初始值10秒   

  22. private boolean isLaunchHeartcheck = false;//是否已启动心跳检测   

  23. private boolean isNetworkConnect = false; //网络是否已连接   

  24. private static String host = "";   

  25. private static int port;   

  26. static InputStream inStream = null;   

  27. static OutputStream outStream = null;   

  28. private static Logger log =Logger.getLogger
    (SocketConnection.class);   

  29. private static SocketConnection socketConnection = null;   

  30. private static java.util.Timer heartTimer=null;     

  31. //private final Map<String, Object> recMsgMap= Collections.
    synchronizedMap(new HashMap<String, Object>());   

  32. private final ConcurrentHashMap<String, Object> recMsgMap 
    = new ConcurrentHashMap<String, Object>();   

  33. private static Thread receiveThread = null;   

  34. private final ReentrantLock lock = new ReentrantLock();   

  35. private SocketConnection(){   

  36. Properties conf = new Properties();   

  37. try {   

  38. conf.load(SocketConnection.class.getResourceAsStream
    ("test.conf"));   

  39. this.timeout = Integer.valueOf(conf.getProperty("timeout"));   

  40. init(conf.getProperty("ip"),Integer.valueOf
    (conf.getProperty("port")));   

  41. } catch(IOException e) {   

  42. log.fatal("socket初始化异常!",e);   

  43. throw new RuntimeException("socket初始化异常,请检查配置参数");   

  44. }   

  45. }   

  46.    

  47. public static SocketConnection getInstance() {   

  48. if(socketConnection==null) {   

  49. synchronized(SocketConnection.class) {   

  50. if(socketConnection==null) {   

  51. socketConnection = new SocketConnection();   

  52. return socketConnection;   

  53. }   

  54. }   

  55. }   

  56. return socketConnection;   

  57. }   

  58. private void init(String host,int port) throws IOException {   

  59. InetSocketAddress addr = new InetSocketAddress(host,port);   

  60. socket = new Socket();   

  61. synchronized (this) {   

  62. log.info("【准备与"+addr+"建立连接】");   

  63. socket.connect(addr, timeout);   

  64. log.info("【与"+addr+"连接已建立】");   

  65. inStream = socket.getInputStream();   

  66. outStream = socket.getOutputStream();   

  67. socket.settcpnodelay(true);//数据不作缓冲,立即发送   

  68. socket.setSoLinger(true, 0);//socket关闭时,立即释放资源   

  69. socket.seTKEepAlive(true);   

  70. socket.setTrafficClass(0x04|0x10);//高可靠性和最小延迟传输   

  71. isNetworkConnect=true;   

  72. receiveThread = new Thread(new ReceiveWorker());   

  73. receiveThread.start();   

  74. SocketConnection.host=host;   

  75. SocketConnection.port=port;   

  76. if(!isLaunchHeartcheck)   

  77. launchHeartcheck();   

  78. }   

  79. }   

  80.    

  81. private void launchHeartcheck() {   

  82. if(socket == null)   

  83. throw new IllegalStateException("socket is not 
    established!");   

  84. heartTimer = new Timer();   

  85. isLaunchHeartcheck = true;   

  86. heartTimer.schedule(new TimerTask() {   

  87. public void run() {   

  88. String msgStreamNo = StreamNoGenerator.getStreamNo("kq");   

  89. int mstType =9999;//999-心跳包请求   

  90. SimpleDateFormat dateformate = new SimpleDateFormat
    ("yyyyMMddHHmmss");   

  91. String msgDateTime = dateformate.format(new Date());   

  92. int msgLength =38;//消息头长度   

  93. String commandstr = "00" +msgLength + mstType + msgStreamNo;   

  94. log.info("心跳检测包 -> IVR "+commandstr);   

  95. int reconnCounter = 1;   

  96. while(true) {   

  97. String responseMsg =null;   

  98. try {   

  99. responseMsg = readReqMsg(commandstr);   

  100. } catch (IOException e) {   

  101. log.error("IO流异常",e);   

  102. reconnCounter ++;   

  103. }   

  104. if(responseMsg!=null) {   

  105. log.info("心跳响应包 <- IVR "+responseMsg);   

  106. reconnCounter = 1;   

  107. break;   

  108. } else {   

  109. reconnCounter ++;   

  110. }   

  111. if(reconnCounter >3) {//重连次数已达三次,判定网络连接中断,
    重新建立连接。连接未被建立时不释放   

  112. reConnectToCTCC(); break;   

  113. }   

  114. }   

  115. }   

  116. },1000 * 60*1,1000*60*2);   

  117. }   

  118.    

  119. private void reConnectToCTCC() {   

  120. new Thread(new Runnable(){   

  121. public void run(){   

  122. log.info("重新建立与"+host+":"+port+"的连接");   

  123. //清理工作,中断计时器,中断接收线程,恢复初始变量   

  124. heartTimer.cancel();   

  125. isLaunchHeartcheck=false;   

  126. isNetworkConnect = false;   

  127. receiveThread.interrupt();   

  128. try {   

  129. socket.close();   

  130. } catch (IOException e1) {log.error("重连时,关闭socket连
    接发生IO流异常",e1);}   

  131. //----------------   

  132. synchronized(this){   

  133. for(; ;){   

  134. try {   

  135. Thread.currentThread();   

  136. Thread.sleep(1000 * 1);   

  137. init(host,port);   

  138. this.notifyAll();   

  139. break ;   

  140. } catch (IOException e) {   

  141. log.error("重新建立连接未成功",e);   

  142. } catch (InterruptedException e){   

  143. log.error("重连线程中断",e);   

  144. }   

  145. }   

  146. }   

  147. }   

  148. }).start();   

  149. }   

  150.    

  151. public String readReqMsg(String requestMsg) throws IOException {   

  152. if(requestMsg ==null) {   

  153. return null;   

  154. }   

  155. if(!isNetworkConnect) {   

  156. synchronized(this){   

  157. try {   

  158. this.wait(1000*5); //等待5秒,如果网络还没有恢复,抛出IO流异常   

  159. if(!isNetworkConnect) {   

  160. throw new IOException("网络连接中断!");   

  161. }   

  162. } catch (InterruptedException e) {   

  163. log.error("发送线程中断",e);   

  164. }   

  165. }   

  166. }   

  167. String msgNo = requestMsg.substring(8, 8 + 24);//读取流水号   

  168. outStream = socket.getOutputStream();   

  169. outStream.write(requestMsg.getBytes());   

  170. outStream.flush();   

  171. Condition msglock = lock.newCondition(); //消息锁   

  172. //注册等待接收消息   

  173. recMsgMap.put(msgNo, msglock);   

  174. try {   

  175. lock.lock();   

  176. msglock.await(timeout,TimeUnit.MILLISECONDS);   

  177. } catch (InterruptedException e) {   

  178. log.error("发送线程中断",e);   

  179. } finally {   

  180. lock.unlock();   

  181. }   

  182. Object respMsg = recMsgMap.remove(msgNo); //响应信息   

  183. if(respMsg!=null &&(respMsg != msglock)) {   

  184. //已经接收到消息,注销等待,成功返回消息   

  185. return (String) respMsg;   

  186. } else {   

  187. log.error(msgNo+" 超时,未收到响应消息");   

  188. throw new SocketTimeoutException(msgNo+" 超时,未收到响应消息");   

  189. }   

  190. }   

  191. public void finalize() {   

  192. if (socket != null) {   

  193. try {   

  194. socket.close();   

  195. } catch (IOException e) {   

  196. e.printStackTrace();   

  197. }   

  198. }   

  199. }   

  200. //消息接收线程   

  201. private class ReceiveWorker implements Runnable {   

  202. String intStr= null;   

  203. public void run() {   

  204. while(!Thread.interrupted()){   

  205. try {   

  206. byte[] headBytes = new byte[4];   

  207. if(inStream.read(headBytes)==-1){   

  208. log.warn("读到流未尾,对方已关闭流!");   

  209. reConnectToCTCC();//读到流未尾,对方已关闭流   

  210. return;   

  211. }   

  212. byte[] tmp =new byte[4];   

  213. tmp = headBytes;   

  214. String tempStr = new String(tmp).trim();   

  215. if(tempStr==null || tempStr.equals("")) {   

  216. log.error("received message is null");   

  217. continue;   

  218. }   

  219. intStr = new String(tmp);   

  220. int totalLength =Integer.parseInt(intStr);   

  221. //----------------   

  222. byte[] msgBytes = new byte[totalLength-4];   

  223. inStream.read(msgBytes);   

  224. String resultMsg = new String(headBytes)+ new 
    String(msgBytes);   

  225. //抽出消息ID   

  226. String msgNo = resultMsg.substring(8, 8 + 24);   

  227. Condition msglock =(Condition) recMsgMap.get(msgNo);   

  228. if(msglock ==null) {   

  229. log.warn(msgNo+"序号可能已被注销!响应消息丢弃");   

  230. recMsgMap.remove(msgNo);   

  231. continue;   

  232. }   

  233. recMsgMap.put(msgNo, resultMsg);   

  234. try{   

  235. lock.lock();   

  236. msglock.signalAll();   

  237. }finally {   

  238. lock.unlock();   

  239. }   

  240. }catch(SocketException e){   

  241. log.error("服务端关闭socket",e);   

  242. reConnectToCTCC();   

  243. } catch(IOException e) {   

  244. log.error("接收线程读取响应数据时发生IO流异常",e);   

  245. } catch(NumberFormatException e){   

  246. log.error("收到没良心包,String转int异常,异常字符:"+intStr);   

  247. }   

  248. }   

  249. }   

  250. }   

“如何解决Java Socket通信技术收发线程互斥的问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何解决Java Socket通信技术收发线程互斥的问题

本文链接: https://www.lsjlt.com/news/290293.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何解决Java Socket通信技术收发线程互斥的问题
    本篇内容介绍了“如何解决Java Socket通信技术收发线程互斥的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java Socket...
    99+
    2023-06-17
  • C#开发中如何处理多线程同步和互斥问题
    C#开发中如何处理多线程同步和互斥问题,需要具体代码示例概述:在C#中,多线程的使用成为了常见的开发需求。然而,由于多线程同时操作共享资源可能导致数据不一致或者冲突的问题,因此需要使用同步和互斥机制来解决这些问题。本文将介绍在C#开发中如何...
    99+
    2023-10-22
    多线程 同步 互斥
  • Java线程技术中的死锁问题怎么解决
    这篇文章主要介绍“Java线程技术中的死锁问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java线程技术中的死锁问题怎么解决”文章能帮助大家解决问题。我们知道,使用 synchroniz...
    99+
    2023-06-02
  • java多线程并发问题如何解决
    在Java中,可以使用以下方法来解决多线程并发问题:1. 使用synchronized关键字:可以通过在方法或代码块前加上synch...
    99+
    2023-09-27
    java
  • 并发编程,你是如何处理多线程间的同步和互斥问题的?
    随着计算机技术的不断发展,多核处理器的出现使得多线程编程变得越来越普遍。然而,多线程编程带来的同步和互斥问题也随之而来。在本文中,我们将探讨如何在并发编程中处理多线程间的同步和互斥问题。 同步问题 在多线程编程中,同步问题是指多个线程在...
    99+
    2023-07-23
    bash leetcode 并发
  • Java中的单线程通信如何利用 Socket实现
    这期内容当中小编将会给大家带来有关Java中的单线程通信如何利用 Socket实现,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java Socket实现单线程通信的方法,具体如下:现在做Java直接使用...
    99+
    2023-05-31
    java socket 单线程通信
  • Java项目中的多线程通信如何利用Socket实现
    这期内容当中小编将会给大家带来有关Java项目中的多线程通信如何利用Socket实现,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java Socket实现多线程通信的方法,代码如下:package co...
    99+
    2023-05-31
    java socket 多线程通信
  • redis单线程并发问题如何解决
    Redis是一个单线程的内存数据库,它使用了事件驱动的模型,通过将请求放入一个队列中顺序执行来实现并发处理。但是,在高并发情况下,可...
    99+
    2023-09-11
    redis
  • 如何解决Java多线程死锁问题
    死锁问题 死锁定义 多线程编程中,因为抢占资源造成了线程无限等待的情况,此情况称为死锁。 死锁举例 注意:线程和锁的关系是:一个线程可以拥有多把锁,一个锁只能被一个线程拥有。 当两个...
    99+
    2024-04-02
  • 微信活码技术如何解决微信群二维码失效问题
    我们都知道微信群未满100人之前可以分享群二维码,让我们的粉丝通过扫码进群,但是人数超过100后,发出的二维码就失效了,无法再次扫码进群,因此,很多人会有微信群满100人怎么再加人,今天给大家介绍下活码技术。传统的解决方式可能是,重新建一个...
    99+
    2023-06-04
  • 如何解决Java中SimpleDateFormat线程不安全的问题
    这篇文章将为大家详细讲解有关如何解决Java中SimpleDateFormat线程不安全的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.什么是线程不安全?线程不安全也叫非线程安全,是指多线程执行中...
    99+
    2023-06-15
  • Java项目中的线程安全问题如何解决
    这篇文章给大家介绍Java项目中的线程安全问题如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。解决方案如下:public class Demo_5 { public&nbs...
    99+
    2023-05-31
    java 线程安全 ava
  • 如何解决java调用process线程阻塞的问题
    这篇文章将为大家详细讲解有关 如何解决java调用process线程阻塞的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。java调用process线程阻塞问题项目需求中涉及java调用.bat文件进行...
    99+
    2023-06-15
  • 如何解决Vue依赖收集引发的问题
    这篇文章主要为大家展示了“如何解决Vue依赖收集引发的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决Vue依赖收集引发的问题”这篇文章吧。问题背景在...
    99+
    2024-04-02
  • SpringCloud如何解决服务之间的通信问题
    目录1、如何解决服务之间的通信问题?2、如何在java代码中发起http方式请求?3、实现服务间通信的小案例4、现有RestTemplate方式通信存在的问题?5、解决RestTem...
    99+
    2024-04-02
  • java全局变量多线程问题如何解决
    在Java中,可以使用以下几种方式来解决全局变量多线程问题:1. 使用synchronized关键字:在访问全局变量时,使用sync...
    99+
    2023-08-26
    java
  • Java 对象开发技术中函数的常见问题及解决方法
    Java 是一种面向对象的编程语言,因此,在 Java 的开发中,对于对象的处理是非常重要的。而对象的处理中,函数的使用更是必不可少的。然而,在 Java 对象开发技术中,函数也存在着一些常见问题,本文将介绍这些问题,并给出相应的解决方法...
    99+
    2023-07-05
    对象 开发技术 函数
  • Java多线程编程中的并发安全问题及解决方法
    目录线程安全性死锁定义实现一个死锁查看死锁解决死锁其他线程安全问题单例模式线程安全性 线程安全是指我们所写的代码在并发情况下使用时,总是能表现出正确的行为;反之,未实现线程安全的代码...
    99+
    2023-05-16
    Java多线程并发安全 Java并发安全问题 Java多线程并发
  • Java多线程高并发中如何解决ArrayList与HashSet和HashMap不安全的问题
    这篇文章主要为大家展示了“Java多线程高并发中如何解决ArrayList与HashSet和HashMap不安全的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java多线程高并发中如何解决...
    99+
    2023-06-25
  • 如何解决MySQL线程处于Opening tables的问题
    这篇文章主要介绍了如何解决MySQL线程处于Opening tables的问题,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。本篇文章给大家带来的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作