เมื่อเร็ว ๆ นี้ฉันกำลังเขียนเครื่องมืออัปโหลด FTP และใช้ FTPClient ของ Apache เพื่อปรับปรุงประสิทธิภาพการอัปโหลดฉันได้ใช้วิธีการหลายเธรด แต่การสร้างและการทำลายวัตถุ FTPClient บ่อยครั้งโดยแต่ละเธรดจะทำให้เกิดค่าใช้จ่ายที่ไม่จำเป็นอย่างหลีกเลี่ยงไม่ได้ ดังนั้นจึงเป็นการดีที่สุดที่จะใช้พูลการเชื่อมต่อ FTPClient ที่นี่ ฉันมองผ่าน Apache API อย่างระมัดระวังและพบว่ามันไม่ได้มีการใช้งาน FTPClientpool ดังนั้นฉันจึงต้องเขียน FTPClientpool ด้วยตัวเอง ต่อไปนี้จะแนะนำกระบวนการทั้งหมดของการพัฒนากลุ่มการเชื่อมต่อสำหรับการอ้างอิงของคุณ
เกี่ยวกับพูลวัตถุ
วัตถุบางอย่างมีค่าใช้จ่ายค่อนข้างสูงเช่นการเชื่อมต่อฐานข้อมูล เพื่อลดการใช้ประสิทธิภาพที่เกิดจากการสร้างและทำลายวัตถุบ่อยครั้งเราสามารถใช้เทคโนโลยีการรวมวัตถุเพื่อให้ได้การใช้วัตถุซ้ำ Object Pool ให้กลไกที่สามารถจัดการวงจรชีวิตของวัตถุในพูลวัตถุให้วิธีการรับและปล่อยวัตถุและช่วยให้ลูกค้าสามารถใช้วัตถุในพูลวัตถุได้อย่างง่ายดาย
หากเราต้องการใช้งานกลุ่มวัตถุด้วยตนเองเราจำเป็นต้องทำฟังก์ชั่นต่อไปนี้ให้เสร็จ:
1. หากมีวัตถุในพูลพูลวัตถุควรจะสามารถกลับไปที่ไคลเอนต์ได้
2. หลังจากลูกค้านำวัตถุกลับเข้าไปในสระพวกเขาสามารถนำกลับมาใช้ใหม่ได้
3. พูลวัตถุสามารถสร้างวัตถุใหม่เพื่อตอบสนองความต้องการที่เพิ่มขึ้นของลูกค้า
4. มีกลไกในการปิดสระว่ายน้ำอย่างถูกต้องเพื่อยุติวงจรชีวิตของวัตถุ
ชุดเครื่องมือพูลวัตถุของ Apache
เพื่ออำนวยความสะดวกให้เราพัฒนาพูลวัตถุของเราเองชุดเครื่องมือทั่วไปของพูลที่จัดทำโดย Apache ประกอบด้วยอินเทอร์เฟซและคลาสการใช้งานสำหรับการพัฒนาพูลวัตถุทั่วไป อินเทอร์เฟซพื้นฐานที่สุดสองตัวคือ ObjectPool และ PoolableObjectFactory
มีวิธีการพื้นฐานหลายอย่างในอินเทอร์เฟซ ObjectPool:
1. AddObject (): เพิ่มวัตถุไปยังพูล
2. BorrowObject (): ไคลเอนต์ยืมวัตถุจากพูล
3. returnObject (): ไคลเอนต์ส่งคืนวัตถุไปยังพูล
4. Close (): ปิดพูลวัตถุหน่วยความจำที่สะอาดและปล่อยทรัพยากร ฯลฯ
5. SetFactory (ObjectFactory Factory): จำเป็นต้องใช้โรงงานเพื่อสร้างวัตถุในพูล
วิธีการพื้นฐานหลายอย่างในอินเทอร์เฟซ PlateableObjectFactory:
1. MakeObject (): สร้างวัตถุ
2. DestoryObject (): ทำลายวัตถุ
3. ValidateObject (): ตรวจสอบว่าวัตถุยังคงพร้อมใช้งาน
ผ่านสองอินเทอร์เฟซข้างต้นเราสามารถใช้พูลวัตถุด้วยตัวเอง
ตัวอย่าง: พัฒนากลุ่มวัตถุ ftpclient
เมื่อเร็ว ๆ นี้โครงการกำลังได้รับการพัฒนาที่ต้องใช้การอัปโหลดไฟล์ใน HDFS ไปยังกลุ่มของเซิร์ฟเวอร์ FTP เพื่อปรับปรุงประสิทธิภาพการอัปโหลดเราพิจารณาโดยใช้วิธีการหลายเธรดสำหรับการอัปโหลด เครื่องมือที่ฉันอัปโหลด FTP คือ FTPClient ในแพ็คเกจ Apache Common-Net แต่ Apache ไม่ได้ให้ FTPClientPool ดังนั้นเพื่อลดจำนวนครั้งที่ FTPClient ถูกสร้างและทำลายเราได้พัฒนา FTPClientpool ตัวเองเพื่อนำการเชื่อมต่อ FTPClient กลับมาใช้ใหม่
ผ่านการแนะนำข้างต้นเราสามารถใช้แพ็คเกจสระว่ายน้ำทั่วไปที่จัดทำโดย Apache เพื่อช่วยเราในการพัฒนากลุ่มการเชื่อมต่อ ในการพัฒนาพูลวัตถุอย่างง่ายคุณจะต้องใช้อินเทอร์เฟซ ObjectPool และ PoolableObjectFactory ในแพ็คเกจพูลทั่วไป มาดูการใช้งานที่ฉันเขียน:
เขียนการใช้งานอินเทอร์เฟซ ObjectPool ftpClientPool
นำเข้า java.io.ioexception; นำเข้า java.util.nosuchelementexception; นำเข้า java.util.concurrent.arrayblockingqueue; นำเข้า java.util.concurrent.blockingqueue; นำเข้า java.util.concurrent.timeUnit; org.apache.commons.pool.objectpool; นำเข้า org.apache.commons.pool.poolableobjectFactory;/*** ใช้การเชื่อมต่อ ftpClient พูล*@author Heaven*/คลาสสาธารณะ FTPClientPool ดำเนินการ ObjOctPool <ftpClient> Private Final BlockingQueue <FtpClient> สระว่ายน้ำ; โรงงาน FTPClientFactory สุดท้ายส่วนตัว; / ** * การเริ่มต้นพูลการเชื่อมต่อโรงงานจะต้องถูกฉีดเพื่อให้อินสแตนซ์ ftpClient * @param Factory * @throws Exception */ FTPClientPool สาธารณะ (FTPClientFactory Factory) โยนข้อยกเว้น {นี่ (default_pool_size, โรงงาน); } / ** * * @param maxpoolsize * @param Factory * @throws Exception * / สาธารณะ ftpclientpool (int poolsize, ftpClientfactory Factory) โยนข้อยกเว้น {this.factory = โรงงาน; pool = new ArrayBlockingQueue <ftpClient> (PoolSize*2); initpool (ขนาดพูล); } /** * การเริ่มต้นพูลการเชื่อมต่อโรงงานจะต้องถูกฉีดเพื่อให้อินสแตนซ์ ftpClient * @param maxpoolsize * @throws ยกเว้น * /void private void initpool (int maxpoolsize) โยนข้อยกเว้น {สำหรับ (int i = 0; i <maxpoolsize; i ++) }} / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.objectpool#borrowobject () * / public ftpclient borrowbject () โยนข้อยกเว้น, nosuchelementexception, orderalStateException if (client == null) {client = factory.makeObject (); addobject (); } อื่นถ้า (! factory.validateObject (ไคลเอนต์)) {// ตรวจสอบว่าอย่าผ่าน // ทำให้วัตถุนั้นเป็น unvalidateObject (ไคลเอนต์); // ทำและเพิ่มวัตถุใหม่ลงในไคลเอนต์พูล = Factory.MakeObject (); addobject (); } ส่งคืนไคลเอนต์; } / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.objectPool#returnObject (java.lang.Object) * / โมฆะสาธารณะ returnObject (ไคลเอนต์ ftpClient) โยนข้อยกเว้น {ถ้า (ไคลเอนต์! = null) &&! } catch (ioexception e) {e.printstacktrace (); }}} โมฆะสาธารณะ InvalidateObject (ไคลเอนต์ ftpClient) พ่นข้อยกเว้น {// ลบพูลไคลเอนต์ที่ไม่ถูกต้อง remove (ไคลเอนต์); } / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.objectpool#addobject () * /โมฆะสาธารณะ addoBject () โยนข้อยกเว้น, ungelStateException, unsupportedoperationException {// แทรกวัตถุไปยัง queUe } public int getNumidle () โยน unsupportedoperationException {return 0; } public int getNumactive () โยน unsupportedoperationException {return 0; } โมฆะสาธารณะ Clear () โยนข้อยกเว้น, unsupportedOperationException {} / * (ไม่ใช่ javadoc) * @See org.apache.Commons.pool.ObjectPool#close () * / โมฆะสาธารณะปิด () Factory.DestroyObject (ลูกค้า); }} โมฆะสาธารณะ setFactory (ploseableObjectFactory <FTPClient> โรงงาน) พ่น unlegalStateException, unsupportedOperationException {}}เขียนการใช้งานอินเทอร์เฟซ poolableObjectory อื่น ftpClientFactory
นำเข้า java.io.ioException; นำเข้า org.apache.commons.net.ftp.ftpclient; นำเข้า org.apache.commons.net.ftp.ftpreply; นำเข้า org.apache.Commons.pool.poolableoBjectFactory; com.hdfstoftp.util.ftpclientexception;/*** คลาสโรงงาน ftpclient ให้การสร้างและการทำลายของอินสแตนซ์ ftpClient ผ่านโรงงาน ftpClient*@author สวรรค์*/คลาสสาธารณะ ftpClientFactory การกำหนดค่า FTPClientConfigure ส่วนตัว; // หยุดชั่วคราววัตถุพารามิเตอร์ไปยังโรงงานเพื่ออำนวยความสะดวกในการกำหนดค่าพารามิเตอร์ที่เกี่ยวข้องของ FTPClient FTPClientFactory (ftpClientConfigure config) {this.config = config; } / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.poolableobjectFactory#makeObject () * / public ftpClient makeObject () โยนข้อยกเว้น {ftpClient ftpClient = new ftpClient (); ftpClient.setConnectTimeOut (config.getClientTimeOut ()); ลอง {ftpClient.connect (config.getHost (), config.getport ()); int ตอบ = ftpClient.getReplyCode (); if (! ftpreply.ispositiveCompletion (ตอบกลับ)) {ftpClient.disconnect (); logger.warn ("ftpserver ปฏิเสธการเชื่อมต่อ"); คืนค่า null; } boolean result = ftpClient.login (config.getUserName (), config.getPassword ()); if (! ผลลัพธ์) {โยน ftpClientException ใหม่ ("การเข้าสู่ระบบ ftpClient ล้มเหลว! ชื่อผู้ใช้:" + config.getUserName () + "รหัสผ่าน:" + config.getPassword ()); } ftpClient.setFileType (config.getTransferFileType ()); ftpclient.setBuffersize (1024); ftpClient.setControlencoding (config.getEncoding ()); if (config.getPassiveMode (). เท่ากับ ("true")) {ftpClient.enterLocalPassiveMode (); }} catch (ioexception e) {e.printstacktrace (); } catch (ftpClientException e) {e.printStackTrace (); } ส่งคืน ftpClient; } / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.poolableobjectFactory#destionObject (java.lang.Object) * / โมฆะสาธารณะ destroyObject (ftpClient ftpClient) โยนข้อยกเว้น {try {ถ้า (ftpClient! }} catch (ioexception io) {io.printstacktrace (); } ในที่สุด {// โปรดทราบว่าคุณต้องยกเลิกการเชื่อมต่อการเชื่อมต่อในรหัสสุดท้ายมิฉะนั้นจะทำให้การเชื่อมต่อ FTP ถูกครอบครองลอง {ftpClient.disconnect (); } catch (ioexception io) {io.printstacktrace (); }}} / * (ไม่ใช่ javadoc) * @see org.apache.commons.pool.poolableobjectFactory#validateObject (java.lang.Object) * / public Boolean ValidateObject (ftpClient ftpClient) {ลอง {return ftpClient } catch (ioexception e) {โยน runtimeException ใหม่ ("ไม่สามารถตรวจสอบลูกค้าได้:" + e, e); }} โมฆะสาธารณะ activateObject (ftpClient ftpClient) พ่นข้อยกเว้น {} โมฆะสาธารณะ passivateObject (ftpClient ftpClient) โยนข้อยกเว้น {}}ในที่สุดก็เป็นการดีที่สุดที่จะส่งวัตถุพารามิเตอร์ไปยังโรงงานเพื่ออำนวยความสะดวกให้เราตั้งค่าพารามิเตอร์บางอย่างของ ftpClient
แพ็คเกจ org.apache.commons.pool.impl.contrib;/** * คลาสการกำหนดค่า ftpclient, ห่อหุ้มการกำหนดค่าที่เกี่ยวข้องของ ftpclient * * @author สวรรค์ */คลาสสาธารณะ ftpclientconfigure {โฮสต์สตริงส่วนตัว; พอร์ต int ส่วนตัว; ชื่อผู้ใช้สตริงส่วนตัว; รหัสผ่านสตริงส่วนตัว สตริงส่วนตัว passivemode; การเข้ารหัสสตริงส่วนตัว Private Int ClientTimeout; Int Int เธรดนัมส่วนตัว; Int Int TransferfileType; บูลีนส่วนตัว renameuploaded; retrytimes ส่วนตัว; สตริงสาธารณะ gethost () {return host; } โมฆะสาธารณะ sethost (โฮสต์สตริง) {สิ่งนี้ โฮสต์ = โฮสต์; } public int getPort () {port return; } โมฆะสาธารณะ setport (พอร์ต int) {สิ่งนี้ พอร์ต = พอร์ต; } สตริงสาธารณะ getUserName () {ส่งคืนชื่อผู้ใช้; } โมฆะสาธารณะ setUserName (ชื่อผู้ใช้สตริง) {สิ่งนี้ ชื่อผู้ใช้ = ชื่อผู้ใช้; } สตริงสาธารณะ getPassword () {ส่งคืนรหัสผ่าน; } โมฆะสาธารณะ setPassword (รหัสผ่านสตริง) {สิ่งนี้ รหัสผ่าน = รหัสผ่าน; } สตริงสาธารณะ getPassiveMode () {return passiveMode; } โมฆะสาธารณะ setPassiveMode (String passiveMode) {สิ่งนี้ passiveMode = passiveMode; } สตริงสาธารณะ getEncoding () {return encoding; } โมฆะสาธารณะ setEncoding (การเข้ารหัสสตริง) {สิ่งนี้ การเข้ารหัส = การเข้ารหัส; } public int getClientTimeOut () {ส่งคืนไคลเอ็นต์เวลา; } โมฆะสาธารณะ setClientTimeOut (int clienttimeout) {สิ่งนี้ clientTimeout = clienttimeout; } public int getThreadNum () {return threadNum; } โมฆะสาธารณะ setThreadNum (int threadnum) {สิ่งนี้ ThreadNum = ThreadNum; } สาธารณะ int getTransferFileType () {return transferfileType; } โมฆะสาธารณะ setTransferFileType (int transferfileType) {สิ่งนี้ transferfileType = transferfileType; } บูลีนสาธารณะ iSrenameUploaded () {return renameUploaded; } โมฆะสาธารณะ setRenameUploaded (บูลีน renameUploaded) {สิ่งนี้ RenameUploaded = RenameUploaded; } สาธารณะ int getRetryTimes () {return retrytimes; } โมฆะสาธารณะ setRetryTimes (int retrytimes) {สิ่งนี้ retrytimes = retrytimes; } @Override สตริงสาธารณะ toString () {return "ftpClientConfig [host =" + host + "/n พอร์ต =" + พอร์ต + "/n username =" + ชื่อผู้ใช้ + "/n รหัสผ่าน =" + รหัสผ่าน "/n passiveMode =" + passiveMode + " "/n transferfileType =" + transferfileType + "/n renameUploaded =" + renameUploaded + "/n retryTimes =" + retryTimes + "]"; -คลาสการเชื่อมต่อ FTPClientpool จัดการวัฏจักรชีวิตของวัตถุ FTPClient และรับผิดชอบในการให้ยืมการวางแผนและการทำลายพูล คลาส FTPClientpool ขึ้นอยู่กับคลาส FTPClientFactory ซึ่งใช้ในการสร้างและทำลายวัตถุโดยคลาสวิศวกรรมนี้ FTPClientFactory ยังขึ้นอยู่กับคลาส FTPClientConfigure ซึ่งรับผิดชอบในการห่อหุ้มพารามิเตอร์การกำหนดค่าของ FTPClient ณ จุดนี้กลุ่มการเชื่อมต่อ FTPClient ของเราได้รับการพัฒนา
ควรสังเกตว่า arrayblockingqueue ใช้ใน ftpclientpool เพื่อจัดการและจัดเก็บวัตถุ ftpclient สำหรับการปิดกั้นคิวโปรดดูบทความของฉัน: [Java พร้อมกัน] BlockingQueue
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น