في الآونة الأخيرة ، أكتب أداة تحميل FTP واستخدام FTPClient من Apache. من أجل تحسين كفاءة التحميل ، اعتمدت نهجًا متعدد الخيوط ، لكن إنشاء وتدمير كائنات FTPClient المتكررة من قبل كل مؤشر ترابط سيؤدي حتماً إلى حتمية. لذلك ، من الأفضل استخدام مجموعة اتصال FTPClient هنا. نظرت بعناية من خلال APACHE API ووجدت أنه لم يكن لديه تطبيق لـ FTPCLIENTPOOL ، لذلك اضطررت إلى كتابة FTPCLIENTPOOL بنفسي. سيؤدي ما يلي إلى تقديم العملية الكاملة لتطوير مجموعة اتصال للرجوع إليها.
حول تجمع الكائن
تحتوي بعض الكائنات على ارتفاع نسبيًا ، مثل اتصالات قاعدة البيانات. من أجل تقليل استهلاك الأداء الناجم عن إنشاء الأشياء المتكررة وتدمير الكائنات ، يمكننا استخدام تقنية تجميع الكائنات لتحقيق إعادة استخدام الكائن. يوفر تجمع الكائنات آلية يمكنها إدارة دورة حياة الكائنات في تجمع الكائنات ، ويوفر طريقة للحصول على الكائنات وإطلاقها ، ويسمح للعملاء باستخدام الكائنات بسهولة في تجمع الكائنات.
إذا أردنا تنفيذ تجمع كائنات بأنفسنا ، نحتاج عمومًا إلى إكمال الوظائف التالية:
1. إذا كانت هناك كائنات متوفرة في التجمع ، فيجب أن يكون تجمع الكائن قادرًا على العودة إلى العميل.
2. بعد أن أعاد العميل الكائنات مرة أخرى إلى حمام السباحة ، يمكنهم إعادة استخدامها.
3. يمكن لتجمعات الكائنات إنشاء كائنات جديدة لتلبية الاحتياجات المتزايدة للعملاء
4. هناك آلية لإغلاق المسبح بشكل صحيح لإنهاء دورة حياة الكائن
مجموعة أدوات تجمع كائنات Apache
من أجل تسهيلنا لتطوير تجمع الكائنات الخاصة بنا ، تحتوي مجموعة أدوات البوب المشتركة التي توفرها Apache على بعض الواجهات وفئات التنفيذ لتطوير تجمعات الكائنات المشتركة. الواجهتان الأساسيتان هما ObjectPool و PoolableObjectFactory.
هناك العديد من الطرق الأساسية في واجهة ObjectPool:
1. addObject (): أضف كائن إلى التجمع
2. BorrowObject (): يستعير العميل كائنًا من التجمع
3. returnoBject (): يقوم العميل بإرجاع كائن إلى التجمع
4. إغلاق (): أغلق تجمع الكائنات ، وموارد الذاكرة النظيفة والفرار ، إلخ.
5. setFactory (ObjectFactory Factory): هناك حاجة إلى مصنع لإنشاء كائنات في المجمع.
العديد من الطرق الأساسية في واجهة poolableObjectFactory:
1. MakeObject (): قم بعمل كائن
2. DestoryObject (): تدمير كائن
3.
من خلال الواجهتين أعلاه ، يمكننا تنفيذ تجمع كائن من قبل أنفسنا.
مثال: تطوير تجمع كائن FTPCLIENT
في الآونة الأخيرة ، يجري تطوير المشروع يتطلب تحميل ملفات في HDFS لمجموعة من خوادم FTP. من أجل تحسين كفاءة التحميل ، نفكر بشكل طبيعي في استخدام طرق متعددة الخيوط للتحميل. الأداة التي قمت بتحميلها FTP هي FTPClient في حزمة Apache Common-Net ، لكن Apache لا يوفر FTPClientPool. لذلك من أجل تقليل عدد المرات التي يتم فيها إنشاء FTPClient وتدميرها ، قمنا بتطوير FTPClientPool أنفسنا لإعادة استخدام اتصال FTPClient.
من خلال المقدمة أعلاه ، يمكننا استخدام الحزمة المشتركة التي توفرها Apache لمساعدتنا في تطوير تجمعات الاتصال. لتطوير تجمع كائنات بسيط ، تحتاج فقط إلى تنفيذ واجهات ObjectPool و PoolableObjectFactory في حزمة البول المشتركة. دعونا نلقي نظرة على التنفيذ الذي كتبته:
اكتب تطبيق واجهة ObjectPool FTPClientPool
استيراد java.io.ioException ؛ استيراد java.util.noselementException ؛ import java.util.concurrent.arrayBlockingqueue ؛ org.apache.commons.pool.objectpool ؛ import org.apache.commons.pool.poolableObjectFactory ؛/*** تنفيذ مجموعة اتصال FTPClient* @Author Heaven*/public class ftpclientpool تنفذ ObjectPool <ftpClient> {private int int default = 10 ؛ Plockingqueue النهائي الخاص <FtpClient>. مصنع FTPClientFactory النهائي الخاص ؛ / ** * تهيئة تجمع الاتصال ، يجب حقن المصنع لتوفير مثيل FTPClient * param factory * athrows استثناء */ public ftpclientpool (FTPClientFactory Factory) يلقي الاستثناء {this (default_pool_size ، factory) ؛ } / ** * * @param maxpoolsize * param factory * throws استثناء * / public ftpclientpool (int poolsize ، ftpclientfactory factory) يلقي الاستثناء {this.factory = factory ؛ pool = new ArrayBlockingQueue <FtpClient> (poolsize*2) ؛ initpool (حمامات السباحة) ؛ } /** * تهيئة تجمع الاتصال ، يجب حقن المصنع لتوفير مثيل FTPClient * param maxpoolsize * athrows استثناء * /private void initpool (int maxpoolsize) يلقي استثناء (int i = 0 ؛ i <maxpoolsize ؛ }} / * (غير javadoc) * see org.apache.commons.pool.objectpool#borrowObject () * / public ftpclient borrowObject () رمي الاستثناء ، nosuchelementexception ، alfarkalStateException {ftpclient client = pool.take () ؛ if (client == null) {client = factory.makeObject () ؛ AddObject () ؛ } if if (! factory.validateObject (client)) {// تحقق من عدم تمرير // جعل الكائن pervilityObject (client) ؛ // اصنع وأضف كائنات جديدة إلى العميل البلياردو = Factory.MakeObject () ؛ AddObject () ؛ } إرجاع العميل ؛ } / * (non-javadoc) * see org.apache.commons.pool.objectpool#returnoBject (java.lang.object) * / public void returnoBject (ftpclient client) reats {factory. } catch (ioException e) {E.PrintStackTrace () ؛ }}} public void pervilityObject (ftpClient Client) يلقي استثناء {// إزالة prolidate client pool.remove (client) ؛ } / * (غير javadoc) * see org.apache.commons.pool.objectpool#addObject () * /public void addobject () رمي الاستثناء ، غير alfortedStateException ، unsupportedOperationException {// insert to to the queue pool.offer (factory.makeObject () 3 ، timeUnit.SeConds ؛ } public int getNumidle () يلقي UnsupportedOperationException {return 0 ؛ } public int getNumactive () يلقي UnsupportedOperationException {return 0 ؛ } public void clear () يلقي استثناء ، unsupportedOperationException {} / * (non-javadoc) * see org.apache.commons.pool.objectpool#close () * / public void close () rems stispion {when (pool.iterator (). hasnext ()) {ftpclient client = Factory.DestroyObject (Client) ؛ })اكتب تطبيق واجهة أخرى قابلة للتجمع
استيراد java.io.ioException ؛ import org.apache.commons.net.ftp.ftpclient ؛ import org.apache.commons.net.ftp.ftpreply ؛ import org.apache.commons.pool.poolableObjectFactory ؛ import org.slf4j.logger ؛ import org.slf4j.loggerfactory ؛ يوفر com.hdfstoftp.util.ftpclientexception ؛/*** ftpclient Factory ، إنشاء وتدمير مثيلات FTPClient من خلال FTPClient Factory* @A Heaven*/public class ftpclientfactory تنفذ poolableObjectoraTory <ftpclient> {private static logger = loggerfactory. FTPClientConfigure التكوين الخاص ؛ // إيقاف كائن معلمة إلى المصنع لتسهيل تكوين المعلمات ذات الصلة من FTPCLIENT FTPCLIENTFACTORY (FTPCLIENTCONFIGURE CONFIG) {this.config = config ؛ } / * (non-javadoc) * see org.apache.commons.pool.poolableObjectORATORY#makeObject () * / public ftpclient makeobject () rems {ftpclient ftpclient = new ftpclient () ؛ ftpclient.setConnectTimeout (config.getClientTimeOut ()) ؛ حاول {ftpclient.connect (config.gethost () ، config.getport ()) ؛ int reply = ftpClient.getReplyCode () ؛ if (! ftpreply.ispositivecOption (الرد)) {ftpclient.disconnect () ؛ logger.warn ("رفض ftpserver الاتصال") ؛ العودة لاغية. } النتيجة المنطقية = ftpclient.login (config.getuserName () ، config.getPassword ()) ؛ إذا (! } ftpclient.setFiletype (config.getTransferFileType ()) ؛ ftpclient.setBuffersize (1024) ؛ ftpclient.setControlenCoding (config.getencoding ()) ؛ if (config.getPassiveMode (). equals ("true")) {ftpClient.EnterLocalPassiveMode () ؛ }} catch (ioException e) {E.PrintStackTrace () ؛ } catch (ftpClientException e) {E.PrintStackTrace () ؛ } إرجاع ftpclient ؛ } / * (non-javadoc) * see org.apache.commons.pool.poolableObjectFactory#DestroyoBject (java.lang.object) * / public void destroyoBject (ftpclient ftpclient) revised {try {if (ftpclient! = null && }} catch (ioException io) {io.printstacktrace () ؛ } أخيرًا {// لاحظ أنه يجب عليك فصل الاتصال في الكود أخيرًا ، وإلا فإنه سيؤدي إلى احتلال اتصال FTP Try {ftpClient.Disconnect () ؛ } catch (ioException io) {io.printstacktrace () ؛ }}} / * (غير javadoc) * see org.apache.commons.pool.poolableObjectFactory#validateObject (java.lang.object) * / public boolean validateObject (ftpclient ftpclient) {try {return ftpclient.sendnoop () ؛ } catch (ioException e) {رمي new runTimeException ("فشل في التحقق من صحة العميل:" + e ، e) ؛ }} public void ActivateObject (ftpclient ftpclient) يلقي استثناء {} public void divoryoBject (ftpclient ftpclient) يلقي استثناء {}}أخيرًا ، من الأفضل تمرير كائن معلمة إلى المصنع لتسهيلنا لتعيين بعض المعلمات من FTPClient
حزمة org.apache.commons.pool.impl.contrib ؛/** * فئة التكوين ftpclient ، تغلف التكوين ذي الصلة لـ ftpclient * * Author Heaven */public class ftpClientConfigure {private String Host ؛ منفذ الباحث الخاص ؛ اسم المستخدم الخاص بالسلسلة الخاصة ؛ كلمة مرور السلسلة الخاصة ؛ سلسلة خاصة passivemode. ترميز سلسلة خاصة. خاص int clientTimeout ؛ خاص int threadnum. Private Int TransferFileType ؛ rewamuploaded المنطقي الخاص ؛ محاكات int الخاصة ؛ السلسلة العامة gethost () {return host ؛ } public void sethost (سلسلة مضيف) {هذا. مضيف = مضيف ؛ } public int getPort () {return port ؛ } public void setport (int port) {this. منفذ = منفذ ؛ } السلسلة العامة getUserName () {return username ؛ } public void setusername (string username) {this. اسم المستخدم = اسم المستخدم ؛ } السلسلة العامة getPassword () {return password ؛ } public void setPassword (سلسلة كلمة مرور) {هذا. كلمة المرور = كلمة المرور ؛ } السلسلة العامة getPassiveMode () {return passivemode ؛ } public void setPassiveMode (String passivemode) {this. passivemode = passivemode ؛ } السلسلة العامة getencoding () {return envoding ؛ } setencoding public void (ترميز السلسلة) {هذا. الترميز = الترميز ؛ } public int getClientTimeOut () {return clientTimeout ؛ } public void setClientTimeOut (int clientTimeout) {هذا. clientTimeOut = clientTimeout ؛ } public int getThReadNum () {return threadnum ؛ } public void setThReadNum (int threadnum) {this. threadnum = threadnum ؛ } public int getTransferFiLetype () {return transferfileType ؛ } public void setTransferFileType (int transferfiletype) {this. TransferFileType = transferFileType ؛ } boolean public isrenameuploaded () {return RenameUploaded ؛ ) RENAMEUPLOADED = RENAMEUPLOADED ؛ } public int getRetryTimes () {retrytimes ؛ } public void setRetryTimes (int receptimes) {this. RetryTimes = RetryTimes ؛ } Override public string toString () {return "ftpClientConfig [host =" + host + "/n port =" + port + "/n username =" + username + "/n password =" + password + "/n passivemode =" + passivemode + "/n encoding =" + encoding + " "/n transferfileType =" + transferfileType + "/n renameuploaded =" + RenameUploaded + "/n receptimes =" + retrytimes + "]" ؛ }}تدير فئة مجموعة اتصال FTPClientPool دورة حياة كائن FTPClient ، وهي مسؤولة عن تدمير الإقراض والتخطيط وتدمير البلياردو. تعتمد فئة FTPClientPool على فئة FTPClientFactory ، والتي يتم استخدامها لإنشاء وتدمير الكائنات من خلال هذه الفئة الهندسية ؛ يعتمد FTPClientFactory أيضًا على فئة FTPClientConfigure ، والتي هي المسؤولة عن تغليف معلمات التكوين الخاصة بـ FTPClient. في هذه المرحلة ، تم تطوير مجموعة اتصال FTPClient الخاصة بنا.
تجدر الإشارة إلى أنه يتم استخدام arrayblockingqueue في FTPClientPool لإدارة وتخزين كائنات FTPClient. لحظر قوائم الانتظار ، يرجى الرجوع إلى مقالتي: [Java Concurrency] Blockingqueue
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.