導航:首頁 > 編程語言 > msgpackjava

msgpackjava

發布時間:2023-05-04 07:58:51

1. redis客戶端選型-Jedis、lettuce、Redisson

1.背景

    研發部門對於客戶端選型比較廣泛和隨意,依賴的分支也不統一,感覺就像網路到一個就直接用,或者是有一個功能滿足就換,沒有考慮到其他組的使用情況以及集中維護。

    另外一個是如果作為公司pom腳手架的基本組成部分,需要考慮統一成一個還是多個並存的問題,現在有兩個考量:如果性能不是大問題,建議統一集中為一個就行; 如果需要多個並存,至少不能多於2個客戶端。

2.比較

    官方推薦的java客戶端只有Jedis、lettuce、Redisson,所以這次分析只針對這三個進行。

2.1.概述

    Jedis: redis的Java實現客戶端,提供了比較全面的Redis命令的支持。

    lettuce: Lettuce is a scalable thread-safe Redis client for synchronous, asynchronous and reactive usage. Multiple threads may share one connection if they avoid blocking and transactional operations such as BLPOP and MULTI/EXEC. Lettuce is built with netty. Supports advanced Redis features such as Sentinel, Cluster, Pipelining, Auto-Reconnect and Redis data models.

    Redisson: Redisson是一個在Redis的基礎上實現的Java駐內存數據網格(In-Memory Data Grid)。它不僅提供了一系列的分布式的Java常用對象,還提供了許多分布式服務。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheler service) Redisson提供了使用Redis的最簡單和最便捷的方法。Redisson的宗旨是促進使用者對Redis的關注分離(Separation of Concern),從而讓使用者能夠將精力更集中地放在處理業務答舉邏輯上。

lettuce: 直接看官網的: https://lettuce.io/

2.2.性能

    Jedis的性能比lettuce和Redisson都要差一點,三者的主要差異在於以下:

    1.Jedis使用同步和阻塞IO的方式,不支持非同步;lettuce和Redisson支持非同步,底層是基於netty框架的事件驅動作為通信層。

    2.Jedis設計上就是基於線程不安全來設計,一個連接只能被一個線程使用,但清皮碧是可以結合連接池來提高其性能;lettuce和Redis基於線程安全來設計的,一個連接是被共享使用的,但是也提供了連接池,主要用於事務以及阻塞操作的命令。

    3.lettuce和Redisson支持非同步流的方式。

    一些公開的benchmark結果:

    Redisson和Jedis:

https://dzone.com/articles/redisson-pro-vs-jedis-which-is-faster

    Jedis和lettuce:

https://www.bby.cn/detail.html?id=9108

    上面的測試結果都是比較久遠的,沒找到三者共同參與的性能測試結果。

    沒有做三者的性能基準測試,主要是無目的性、無針對性的條件限制(並發數、數據量、指令kv的握燃大小范圍),很難去做定量和可對比的基準測試(主要是我懶)。

2.3.功能

    Jedis: 提供比較全面的redis原生指令的支持,上層封裝比較弱,集群特性支持度非常低,高級特性幾乎沒有。

    lettuce: 高級redis客戶端,支持各種模式的redis連接和操作,高級特性幾乎沒有。

    Redisson: 高級redis客戶端,支持各種模式的redis連接和操作,同時提供一大堆的實用功能。

    Jedis和lettuce沒什麼功能,就簡單的操作,連分布式鎖都需要自己實現,所以先聊聊Redisson的高級功能,中間偶爾會用Jedis和lettuce做對比。

    1.十幾種編碼方式。

    Redisson是基於對象的操作,對於key對象和value對象可用不同的高級編碼方式:

    jsonJacksonCodec、AvroJacksonCodec、SmileJacksonCodec、CborJacksonCodec、MsgPackJacksonCodec、IonJacksonCodec、KryoCodec、SerializationCodec、FstCodec、LZ4Codec、SnappyCodec、CompositeCodec

    和四種基本的編碼方式:

    JsonJacksonMapCodec、StringCodec、LongCodec、ByteArrayCodec

    而Jedis操作只針對位元組數組, lettuce支持ByteArrayCodec、StringCodec、CipherCodec、CompressionCodec四種。

    按需使用,沒有編碼方式的比對。

2.分布式集合。

    把大集合拆分並均勻分布到各個節點上,集合包括Set、Map、BitSet、Bloom Filter、Spring Cache和Hibernate Cache,並且支持本地緩存。(只有專業版才能用)分布式鎖。

各種各樣的分布式鎖: 可重入鎖ReentrantLock、公平鎖FairLock、聯鎖MultiLock、紅鎖RedLock、讀寫鎖ReadWriteLock、信號量Semaphore、可過期的信號量PermitExpirableSemaphore、計數器CountDownLatch

3.RPC

4.分布式調度任務服務

5.分布式MR

6.復雜多維對象結構和對象引用的支持

7.集群pipeline

    lettuce也支持。

    jedis不支持,jedis連多key(分布在不同節點的)操作都不支持。

8.事務

    提供了XA Transactions標準的實現,可以集成到Spring中。(只有專業版才能用)

9.集群管理工具

    (只有專業版才能用)

10.限流器

    分布式的限流工具(有timeout功能)。

11.自增/分布式ID

12.BloomFilter

13.延遲隊列

2.4.選型

    Spring最早是默認以Jedis作為客戶端, 但是後來改為了lettuce, lettuce與Jedis相比比較明顯的特點是非同步和線程安全, 底層是netty大殺器作為通信層, 性能比Jedis的線程不安全+連接池要好。

    Redisson是以其強大的功能以及面向對象的設計優於其他兩者。

    根據我們的業務需要:

    1.限流

    2.分布式鎖

    3.緩存

    4.GID生成

    5.延時隊列

    6.lua腳本

    7.請求合並

    Redisson都能滿足,實際上單是使用Redisson作為Spring的客戶端就足夠了。

    個人傾向lettuce + Redisson。

2. 請教python與java之間rpc通信,rabbitmq相關

JSON 簡單攔衡禪粗暴
msgPack格攔衫式, 支持廣泛, 類似 JSON , 但是效率更高
Thrift 全簡塵家桶, 爽爽爽
protobuf + gRpc

3. java開發中如何巧妙的使用Redis提高性能

樓主您好
把Redis作為緩存,將一些熱點數據放到Redis中,讀取時先讀redis,載讀db。
至於內減少內存,注意容:Redis中數據的過期策略;選擇合適的數據結構,例如:選擇hash而非string;數據存儲進redis前使用序列化工具壓縮,推薦MsgPack。
推薦知乎:https://www.hu.com/question/29548367

4. msgpack在java/c和go中序列化的區別

序列化其實很好理解,假如你現在做一個項目圓碧旦,項目是分工合作的,並且你喝其他小組成員不在同一個城市,那麼你要如何把你寫的那些類給其他小組成員呢?這個時候就要用到序列化了,簡單的說:序列化就是將內存中的類或者對象(你寫的類都是存儲在內存中的)變成可以存儲到存儲媒介中的流,你將類序列化成流之橘擾後可以通過互聯網傳輸給別人,你也可以反序列化將慧培別人的序列化流轉換成內存中的對象,就這么簡單

5. ubuntu 怎麼導入python工程

在Ubuntu虛擬機中部署了。

項目中用到了的python模板有 redis zookeeper msgpack setuptools tornado ujson
軟體安裝包如下:
eclipse-jee-luna-R-linux-gtk-x86_64.tar.gz
jdk-7u71-linux-x64.gz
zookeeper-3.4.6.tar.gz
zkpython-master.zip
msgpack-python-0.3.0.tar.gz
Python-2.7.8.tar.xz
redis-2.6.14.tar.gz
redis-py-2.6.2.zip
setuptools-3.4.3.tar.gz
tornado-4.0.tar.gz
ujson-1.30.zip

1、安裝jdk ,直接解壓到/usr/local,然後配置環境變數即可
我把環境變數放到/etc/profile中了,當然你也可以放到.bashrc中
#add java config
export JAVA_HOME=/usr/local/jdk1.7.0_71
export JRE_HOME=/usr/local/jdk1.7.0_71/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

最後保存profile文件,並命令行執行source /etc/profile 使其生效

2、eclipse 安裝解壓即可
tar -zxvf eclipse-jee-luna-R-linux-gtk-x86_64.tar.gz

直接eclipse啟動時如果發現界面沒menu,應該是由於Ubuntu和eclipse的一個沖突導致的
#slove the menu not find
export UBUNTU_MENUPROXY=0
./eclipse

3、python 安裝,Ubuntu中自帶了python2.7

4、eclipse 中安裝pydev 插件

5、python tornado 安裝
解壓tornado包 tar -xzvf tornado-4.0.tar.gz
python setup.py build
python setup.py install
其它模塊基本上都是如此安裝

在安裝zookeeper時需要注意下,應先安裝python編譯環境包,在安裝zookeeper ,最後安裝zython插件模塊
sudo apt-get install build-essential python-dev
tar -xzvf zookeeper-3.4.6.tar.gz
cd zookeeper-3.4.6/
cd src/c
.configure
make & sudo make install
unzip zkpython-master.zip
python setup.py install
這樣python就安裝了zookeeper模塊了
最後使用eclipse啟動tornado時,zookeeper報錯
ImportError: libzookeeper_mt.so.2
查找發現這個文件在系統/usr/local/lib中是存在的,所以應該是系統沒有找到這個動態鏈接庫,將

export LD_LIBRARY_PATH=/usr/local/lib/

寫入.bashrc文件中 source 並重啟啟動eclipse tornado done

6. Java架構的路上必學知識點,你又知道多少

Jenkins多套環境(test/pre/proction)系統自動化發布
Jenkins自動發布到遠程主機
MavenMaven私服搭建setting.xml文件剖析pom.xml詳解Maven實用插件教學(靜態代碼檢查、生成可執行jar包)profile使用
源碼分析
源碼分析 Spring源碼分析
Spring IOC的實現原理Spring BeanFactory源碼分析Spring AOP的實現原理及配置文件詳解Spring AOP的各種應用場景分析Spring MVC與Struts對比Spring HandlerMapping詳解手寫實現SpringMVC框架Spring與各種框架集成原理Spring JDBC操作原理基於Spring JDBC手寫ORM框架
MyBatis源碼分析
MyBatis3簡介MyBatis3 SqlMap那些事兒資料庫連接池到底是什麼MyBatis3 SessionFactory實現原理MyBatis3 配置文件詳解MyBatis3 事務管理與集成淺談HibernateMyBatis3與Hibernate框架對比Netty源碼分析
NIO通信原理剖析深入了解NIO緩沖區Buffer
NIO Selector原理AIO編程Netty產生的背景以及基礎入門
Netty高性能之道Netty的HTTP與Socket通信原理利用Netty搭建高性能的
WebSocket聊天室
Netty聊天室客戶端架構實現Netty的編碼解碼
Netty的拆包粘包操作MsgPack原理講解及各種序列化框架對比MsgPack與Netty整合
Netty HTTP通信與Spring整合Netty RPC架構Netty與各種架構整合以及Netty源碼分析
性能調優
性能調優 JVMJVM內存模型JVM運行時數據區垃圾回收機制GC日誌詳解
根據GC日誌調優系統,調優不靠碰運氣!Mysql資料庫優化
資料庫底層數據結構索引數據存儲結構 innodb詳解SQL調優及原理分庫、分表實現Nginx調優動靜資源分離
nginx參數詳解nginx + lua使用應用:ip過濾,扛DDOSTomcat調優
Tomcat源碼、架構分析Tomcat具體調優參數設置Tomcat壓力基準測試Tomcat NIO配置

7. Java語言打包成Jar包經過IKVM生成dll文件,在Unity里可以使用嗎,怎麼使用。using引用還可以嗎

unity不支持java語言

8. java如何把msgpack類型的數據轉成對應的屬性

MessagePack是一派伍種高效的二進制序列化格式。它允許您像JSON一樣在多個語言之間交換數據。但是,它更快並且更小。小整數被編碼為一個位元組,和典型的短字元串只需要畢羨差除了字元串本身的一個額外位元組。
.MessagePack的使用
創建一個bean類,注意在類的前面需要加上@Message
@Messagepublic class Info{private String name;private String id;public String getId(){return id;}public void setId(String id){this.id = id;}public String getName(){return name;}public void setName(String name){this.name = name;}@Overridepublic String toString(){return "name : "+ name +", id : "+ id;}}

使用MessagePack對數據手皮進行序列化:
MessagePack messagePack = new MessagePack();//序列化Info info = new Info();info.setId("11111");info.setName("chyss");

byte[] bs = messagePack.write(info);

把接收到的byte[ ] bs 反序列化:
//反序列化Info infoOut = messagePack.read(bs, Info.class);

9. rpc的實現機制是什麼

RPC 的全稱是 Remote Procere Call 是一種進程間通信方式。它允許程序調用另一個地址空間(通常是共享網路的另一台機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即無論是調用本地介面/服務的還是遠程的介面/服務,本質上編寫的調用代碼基本相同。

比如兩台伺服器A,B,一個應用部署在A伺服器上,想要調用B伺服器上應用提供的函數或者方法,由於不在一個內存空間,不能直接調用,這時候需要通過就可以應用RPC框架的實現來解決。

RPC 會隱藏底層的通訊細節(不需要直接處理Socket通訊或Http通訊)

RPC 是一個請求響應模型。客戶端發起請求,伺服器返回響應(類似於Http的工作方式)

RPC 在使用形式上像調用本地函數(或方法)一樣去調用遠程的函數(或方法)。

二、常見RPC框架

幾種比較典型的RPC的實現和調用框架。

(1)RMI實現,利用java.rmi包實現,基於Java遠程方法協議(Java Remote Method Protocol)

和java的原生序列化。

(2)Hessian,是一個輕量級的remoting onhttp工具,使用簡單的方法提供了RMI的功能。 基於HTTP協議,採用二進制編解碼。

(3)THRIFT是一種可伸縮的跨語言服務的軟體框架。thrift允許你定義一個描述文件,描述數據類型和服務介面。依據該文件,編譯器方便地生成RPC客戶端和伺服器通信代碼。

二、RPC框架實現原理

在RPC框架中主要有三個角色:Provider、Consumer和Registry。如下圖所示:

RPC框架面試總結-RPC原理及實現

節點角色說明:

* Server: 暴露服務的服務提供方。

* Client: 調用遠程服務的服務消費方。

* Registry: 服務注冊與發現的注冊中心。

三、RPC調用流程

RPC基本流程圖:

RPC框架面試總結-RPC原理及實現

一次完整的RPC調用流程(同步調用,非同步另說)如下:

1)服務消費方(client)調用以本地調用方式調用服務;

2)client stub接收到調用後負責將方法、參數等組裝成能夠進行網路傳輸的消息體;

3)client stub找到服務地址,並將消息發送到服務端;

4)server stub收到消息後進行解碼;

5)server stub根據解碼結果調用本地的服務;

6)本地服務執行並將結果返回給server stub;

7)server stub將返回結果打包成消息並發送至消費方;

8)client stub接收到消息,並進行解碼;

9)服務消費方得到最終結果。

RPC框架的目標就是要2~8這些步驟都封裝起來,讓用戶對這些細節透明。

四、服務注冊&發現

RPC框架面試總結-RPC原理及實現

服務提供者啟動後主動向注冊中心注冊機器ip、port以及提供的服務列表;

服務消費者啟動時向注冊中心獲取服務提供方地址列表,可實現軟負載均衡和Failover;

五、使用到的技術

1、動態代理

生成 client stub和server stub需要用到 Java 動態代理技術 ,我們可以使用JDK原生的動態代理機制,可以使用一些開源位元組碼工具框架 如:CgLib、Javassist等。

2、序列化

為了能在網路上傳輸和接收 Java對象,我們需要對它進行 序列化和反序列化操作。

* 序列化:將Java對象轉換成byte[]的過程,也就是編碼的過程;

* 反序列化:將byte[]轉換成Java對象的過程;

可以使用Java原生的序列化機制,但是效率非常低,推薦使用一些開源的、成熟的序列化技術,例如:protobuf、Thrift、hessian、Kryo、Msgpack

關於序列化工具性能比較可以參考:jvm-serializers

3、NIO

當前很多RPC框架都直接基於netty這一IO通信框架,比如阿里巴巴的HSF、bbo,Hadoop Avro,推薦使用Netty 作為底層通信框架。

4、服務注冊中心

可選技術:

* Redis

* Zookeeper

* Consul

* Etcd

10. 編程技巧:Java串口通信簡介

嵌入式系統或感測器網路的很多應用和測試都需要通過PC機與嵌入式設備或感測器節點進行通信 其中 最常用的介面就是RS 串口和並口(鑒於USB介面的復雜性以及不需要很大的數據傳輸量 USB介面用在這里還是顯得過於奢侈 況且目前除了SUN有一個支持USB的包之外 我還沒有看到其他直接支持USB的Java類庫) SUN的CommAPI分別提供了對常用的RS 串列埠和IEEE 並行埠通訊的支持 RS C(又稱EIA RS C 以下簡稱RS )是在 年由美國電子工業協會(EIA)聯合貝爾系統 數據機廠家及計算機終端生產廠家共同制定的用於串列通訊的標准 RS 是一個全雙工的通訊協議 它可以同時進行數據接收和發送的工作

常見的Java串口包

目前 常見的Java串口包有SUN在 年發布的串口通信API m jar(Windows下) m jar(Linux/Solaris);IBM的串口通信API以及一個開源的實現 鑒於在Windows下SUN的API比較常用以及IBM的實現和SUN的在API層面都是一樣的 那個開源的實現又不像兩家大廠的產品那樣讓人放心 這里就只介紹SUN的串口通信API在Windows平台下的使用

串口包的安裝(Windows下)

到SUN的網站下載javam win zip 包含的東西如下所示

按照其使用說明(l)的說法 要想使用串口包進行串口通信 除了設置好環境變數之外 還要將win dll復制到 in目錄下;將m jar復制到 lib;把m properties也同樣拷貝到 lib目錄下 然而在真正運行使用串口包的時候 僅作這些是不夠的 因為通常當運行 java MyApp 的時候 是由JRE下的虛擬機啟動MyApp的 而我們只復制上述文件到JDK相應目錄下 所以應用程序將會提示找不到串口 解決這個問題的方法很簡單 我們只須將上面提到的文件放到JRE相應的目錄下就可以了

值得注意的是 在網路應用程序中使用串口API的時候 還會遇到其他更復雜問題 有興趣的話 你可以查看CSDN社區中 關於網頁上Applet用javam 讀取客戶端串口的問題 的帖子

串口API概覽

m CommPort

這是用於描述一個被底層系統支持的埠的抽象類 它包含一些高層的IO控制方法 這些方法對於所有不同的通訊埠來說是通用的 SerialPort 和ParallelPort都是它的子類 前者用於控制串列埠而後者用於控這並口 二者對於各自底層的物理埠都有不同的控制方法 這里我們只關心SerialPort

m CommPortIdentifier

這個類主要用於對串口進行管理和設置 是對串口進行訪問控制的核心類 主要包括以下方法

l 確定是否有可用的通信埠

l 為IO操作打開通信埠

l 決定埠的所有權

l 處理埠所有權的爭用

l 管理埠所有權變化引發的事件(Event)

m SerialPort

這個類用於描述一個RS 串列通信埠的底層介面 它定義了串口通信所需的最小功能集 通過它 用戶可以直接對串口進行讀 寫及設置工作

串口API實例

大段的文字怎麼也不如一個小例子來的清晰 下面我們就一起看一下串口包自帶的例子 SerialDemo中的一小段代碼來加深對串口API核心類的使用方法的認識

列舉出本機所有可用串口

voidlistPortChoices(){ CommPortIdentifierportId; Enumerationen=CommPortIdentifier getPortIdentifiers(); //iteratethroughtheports while(en hasMoreElements()){ portId=(CommPortIdentifier)en nextElement(); if(portId getPortType()==CommPortIdentifier PORT_SERIAL){ System out println(portId getName()); } } portChoice select(parameters getPortName()); }

以上代碼可以列舉出當前系統所有可用的串口名稱 我的機器上輸出的結果是 和

串口參數的配置

串口一般有如下參數可以在該串口打開以前配置進行配置

包括波特率 輸入/輸出流控制 數據位數 停止位和齊偶校驗

SerialPortsPort; try{ sPort setSerialPortParams(BaudRate Databits Stopbits Parity); //設置輸入/輸出控制流 sPort setFlowControlMode(FlowControlIn|FlowControlOut); }catch(){}

串口的讀寫

對串口讀寫之前需要先打開一個串口

CommPortIdentifierportId=CommPortIdentifier getPortIdentifier(PortName); try{ SerialPortsPort=(SerialPort)portId open( 串口所有者名稱 超時等待時間); }catch(PortInUseExceptione){//如果埠被佔用就拋出這個異常 (e getMessage()); } //用於對串口寫數據 OutputStreamos=newBufferedOutputStream(sPort getOutputStream()); os write(intdata); //用於從串口讀數據 InputStreamis=newBufferedInputStream(sPort getInputStream()); intreceivedData=is read();

讀出來的是int型 你可以把它轉換成需要的其他類型

這里要注意的是 由於Java語言沒有無符號類型 即所有的類型都是帶符號的 在由byte到int的時候應該尤其注意 因為如果byte的最高位是 則轉成int類型時將用 來佔位 這樣 原本是 的byte類型的數變成int型就成了 這是很嚴重的問題 應該注意避免

串口通信的通用模式及其問題

終於嘮叨完我最討厭的基礎知識了 下面開始我們本次的重點 串口應用的研究 由於向串口寫數據很簡單 所以這里我們只關注於從串口讀數據的情況 通常 串口通信應用程序有兩種模式 一種是實現SerialPortEventListener介面 監聽各種串口事件並作相應處理;另一種就是建立一個獨立的接收線程專門負責數據的接收 由於這兩種方法在某些情況下存在很嚴重的問題(至於什麼問題這里先賣個關子J) 所以我的實現是採用第三種方法來解決這個問題

事件監聽模型

現在我們來看看事件監聽模型是如何運作的

l 首先需要在你的埠控制類(例如SManager)加上 implements SerialPortEventListener

l 在初始化時加入如下代碼

try{ SerialPortsPort addEventListener(SManager); }catch(TooManyListenersExceptione){ sPort close(); ( toomanylistenersadded ); } sPort notifyOnDataAvailable(true);

l 覆寫public void serialEvent(SerialPortEvent e)方法 在其中對如下事件進行判斷

BI 通訊中斷

CD 載波檢測

CTS 清除發送

DATA_AVAILABLE 有數據到達

DSR 數據設備准備好

FE 幀錯誤

OE 溢位錯誤

OUTPUT_BUFFER_EMPTY 輸出緩沖區已清空

PE 奇偶校驗錯

RI 振鈴指示

一般最常用的就是DATA_AVAILABLE 串口有數據到達事件 也就是說當串口有數據到達時 你可以在serialEvent中接收並處理所收到的數據 然而在我的實踐中 遇到了一個十分嚴重的問題

首先描述一下我的實驗 我的應用程序需要接收感測器節點從串口發回的查詢數據 並將結果以圖標的形式顯示出來 串口設定的波特率是 川口每隔 毫秒返回一組數據(大約是 位元組左右) 周期(即持續時間)為 秒 實測的時候在一個周期內應該返回 多個位元組 而用事件監聽模型我最多隻能收到不到 位元組 不知道這些位元組都跑哪裡去了 也不清楚到底丟失的是那部分數據 值得注意的是 這是我將serialEvent()中所有處理代碼都注掉 只剩下列印代碼所得的結果 數據丟失的如此嚴重是我所不能忍受的 於是我決定採用其他方法

串口讀數據的線程模型

這個模型顧名思義 就是將接收數據的操作寫成一個線程的形式:

(){ ThreadreadDataProcess=newThread(newRunnable(){ publicvoidrun(){ while(newData!= ){ try{ newData=is read(); System out println(newData); //其他的處理過程 ……… }catch(IOExceptionex){ System err println(ex); return; } } readDataProcess start(); }

在我的應用程序中 我將收到的數據打包放到一個緩存中 然後啟動另一個線程從緩存中獲取並處理數據 兩個線程以生產者—消費者模式協同工作 數據的流向如下圖所示

這樣 我就圓滿解決了丟數據問題 然而 沒高興多久我就又發現了一個同樣嚴重的問題 雖然這回不再丟數據了 可是原本一個周期( 秒)之後 感測器節電已經停止傳送數據了 但我的串口線程依然在努力的執行讀串口操作 在控制台也可以看見收到的數據仍在不斷的列印 原來 由於感測器節點發送的數據過快 而我的接收線程處理不過來 所以InputStream就先把已到達卻還沒處理的位元組緩存起來 於是就導致了明明感測器節點已經不再發數據了 而控制台卻還能看見數據不斷列印這一奇怪的現象 唯一值得慶幸的是最後收到數據確實是 左右位元組 沒出現丟失現象 然而當處理完最後一個數據的時候已經快 分半鍾了 這個時間遠遠大於節點運行周期 這一延遲對於一個實時的顯示系統來說簡直是災難!

後來我想 是不是由於兩個線程之間的同步和通信導致了數據接收緩慢呢?於是我在接收線程的代碼中去掉了所有處理代碼 僅保留列印收到數據的語句 結果依然如故 看來並不是線程間的通信阻礙了數據的接收速度 而是用線程模型導致了對於發送端數據發送速率過快的情況下的數據接收延遲 這里申明一點 就是對於數據發送速率不是如此快的情況下前面者兩種模型應該還是好用的 只是特殊情況還是應該特殊處理

第三種方法

痛苦了許久(Boss天天催我L)之後 偶然的機會 我聽說TinyOS中(又是開源的)有一部分是和我的應用程序類似的串口通信部分 於是我下載了它的 x版的Java代碼部分 參考了它的處理方法 解決問題的方法說穿了其實很簡單 就是從根源入手 根源不就是接收線程導致的嗎 那好 我就乾脆取消接收線程和作為中介的共享緩存 而直接在處理線程中調用串口讀數據的方法來解決問題(什麼 為什麼不把處理線程也一並取消? 都取消應用程序界面不就鎖死了嗎?所以必須保留)於是程序變成了這樣

publicbyte[]getPack(){ while(true){ //PacketLength為數據包長度 byte[]msgPack=newbyte[PacketLength]; for(inti= ;i<PacketLength;i++){ if((newData=is read())!= ){ msgPack[i]=(byte)newData; System out println(msgPack[i]); } } returnmsgPack; } }

在處理線程中調用這個方法返回所需要的數據序列並處理之 這樣不但沒有丟失數據的現象行出現 也沒有數據接收延遲了 這里唯一需要注意的就是當串口停止發送數據或沒有數據的時候is read()一直都返回 如果一旦在開始接收數據的時候發現 就不要理它 繼續接收 直到收到真正的數據為止

結束語

lishixin/Article/program/Java/hx/201311/26605

閱讀全文

與msgpackjava相關的資料

熱點內容
桌面雲配置文件分離 瀏覽:505
iphone5如何升級4g網路 瀏覽:5
團購是在哪個app 瀏覽:897
打開多個word文檔圖片就不能顯示 瀏覽:855
騰訊新聞怎麼切換版本 瀏覽:269
app安裝失敗用不了 瀏覽:326
桌面文件滑鼠點開會變大變小 瀏覽:536
手機誤刪系統文件開不了機 瀏覽:883
微信兔子甩耳朵 瀏覽:998
android藍牙傳文件在哪裡 瀏覽:354
蘋果6s軟解是真的嗎 瀏覽:310
c語言代碼量大 瀏覽:874
最新網路衛星導航如何使用 瀏覽:425
以下哪些文件屬於圖像文件 瀏覽:774
zycommentjs 瀏覽:414
確認全血細胞減少看哪些數據 瀏覽:265
文件有哪些要求 瀏覽:484
cad打開時會出現兩個文件 瀏覽:65
什麼是轉基因網站 瀏覽:48
手柄設備有問題代碼43 瀏覽:921

友情鏈接