Baru -baru ini, saya menulis alat unggahan FTP dan menggunakan FTPClient Apache. Untuk meningkatkan efisiensi unggahan, saya telah mengadopsi pendekatan multi-threaded, tetapi sering penciptaan dan penghancuran objek FTPClient oleh masing-masing utas pasti akan menyebabkan overhead yang tidak perlu. Oleh karena itu, yang terbaik adalah menggunakan kumpulan koneksi FTPClient di sini. Saya dengan hati -hati melihat melalui Apache API dan menemukan bahwa itu tidak memiliki implementasi FTPClientPool, jadi saya harus menulis FTPClientPool sendiri. Berikut ini akan memperkenalkan seluruh proses pengembangan kumpulan koneksi untuk referensi Anda.
Tentang kumpulan objek
Beberapa objek memiliki overhead yang relatif tinggi, seperti koneksi basis data. Untuk mengurangi konsumsi kinerja yang disebabkan oleh seringnya penciptaan dan penghancuran objek, kita dapat menggunakan teknologi pengumpulan objek untuk mencapai penggunaan kembali objek. Object Pool menyediakan mekanisme yang dapat mengelola siklus hidup objek di kumpulan objek, menyediakan metode untuk mendapatkan dan melepaskan objek, dan memungkinkan klien untuk dengan mudah menggunakan objek di kumpulan objek.
Jika kita ingin menerapkan kumpulan objek sendiri, kita biasanya perlu menyelesaikan fungsi -fungsi berikut:
1. Jika ada objek yang tersedia di kumpulan, kumpulan objek harus dapat kembali ke klien.
2. Setelah klien memasukkan objek kembali ke kolam, mereka dapat menggunakannya kembali.
3. Kolam objek dapat membuat objek baru untuk memenuhi kebutuhan klien yang semakin besar
4. Ada mekanisme untuk menutup kolam renang dengan benar untuk mengakhiri siklus hidup objek
Toolkit Objek Pool Apache
Untuk memfasilitasi kami untuk mengembangkan kumpulan objek kami sendiri, toolkit umum yang disediakan oleh Apache berisi beberapa antarmuka dan kelas implementasi untuk mengembangkan kumpulan objek umum. Dua antarmuka paling dasar adalah ObjectPool dan PoolableObjectFactory.
Ada beberapa metode dasar dalam antarmuka ObjectPool:
1. AddObject (): Tambahkan objek ke kumpulan
2. BorrowObject (): Klien meminjam objek dari kumpulan
3. returnObject (): Klien mengembalikan objek ke kumpulan
4. Tutup (): Tutup kumpulan objek, memori bersih dan lepaskan sumber daya, dll.
5. SetFactory (Factory ObjectFactory): Sebuah pabrik diperlukan untuk membuat objek di kumpulan.
Beberapa metode dasar dalam antarmuka PoolableObjectFactory:
1. MakeObject (): Buat objek
2. DestoryObject (): Hancurkan objek
3. ValidateBject (): Verifikasi apakah suatu objek masih tersedia
Melalui dua antarmuka di atas, kita dapat menerapkan kumpulan objek sendiri.
Contoh: Kembangkan kumpulan objek FTPClient
Baru -baru ini, sebuah proyek sedang dikembangkan yang membutuhkan pengunggahan file di HDF ke sekelompok server FTP. Untuk meningkatkan efisiensi unggahan, kami secara alami mempertimbangkan untuk menggunakan metode multi-threaded untuk mengunggah. Alat yang saya unggah FTP adalah FTPClient dalam paket net biasa Apache, tetapi Apache tidak menyediakan FTPClientPool. Jadi untuk mengurangi berapa kali ftpClient dibuat dan dihancurkan, kami mengembangkan FTPClientPool sendiri untuk menggunakan kembali koneksi FTPClient.
Melalui pengantar di atas, kami dapat menggunakan paket kolom-umum yang disediakan oleh Apache untuk membantu kami dalam mengembangkan kumpulan koneksi. Untuk mengembangkan kumpulan objek sederhana, Anda hanya perlu menerapkan antarmuka ObjectPool dan PoolableObjectFactory dalam paket umum-kolam. Mari kita lihat implementasi yang saya tulis:
Tulis Implementasi Antarmuka ObjectPool FTPClientPool
Impor java.io.ioException; impor java.util.nosuchelementException; impor java.util.concurrent.arrayblockingqueue; impor java.util.concurrent.blockqueue; import java.util.concurrent.timeunit; import org.apache.common. org.apache.commons.pool.objectpool; impor org.apache.commons.pool.poolableObjectFactory;/*** Implementasikan kumpulan koneksi ftpClient*@author surga*/kelas publik ftpclientpool odypool = 10; kumpulan blockingqueue akhir pribadi <ftpClient>; pabrik ftpclientfactory final swasta; / ** * Menginisialisasi kumpulan koneksi, sebuah pabrik perlu disuntikkan untuk memberikan instance ftpClient * @param factory * @throws Exception */ public ftpClientPool (pabrik ftpClientFactory) melempar pengecualian {this (default_pool_size, factory); } / ** * * @param maxpoolsize * @param factory * @throws Exception * / public ftpclientpool (int poolsize, ftpClientFactory factory) melempar pengecualian {this.factory = factory; pool = arrayblockingqueue baru <ftpClient> (poolsize*2); initpool (poolsize); } /** * Menginisialisasi kumpulan koneksi, sebuah pabrik perlu disuntikkan untuk memberikan instance ftpClient * @param maxpoolsize * @throws Exception * /private void initpool (int maxpoolSize) melempar pengecualian {for (int i = 0; i <maxpoolsize; i ++) {// Add Objek ke kumpulan kumpulan (maxpoolSize (i ++) {// Add Objek ke kumpulan kumpulan (maxPoolSize (i ++) {// Add Objek ke kumpulan kumpulan (maxPoolSize (i ++) {// Add Object ke pool pool (iRICE (I <maxpoolSize; i ++) {// Add Object ke The Pools (int i = 0; }} / * (non-javadoc) * @see org.apache.commons.pool.objectpool#borrowObject () * / public ftpClient BorrowObject () melempar Exception, NosuchelementException, IllegalStateException {ftpClient Client = pool.take (); if (client == null) {client = factory.makeObject (); addObject (); } lain jika (! factory.validateObject (klien)) {// verifikasi untuk tidak lulus // membuat objek tidak validateObject (klien); // buat dan tambahkan objek baru ke klien klien = factory.makeObject (); addObject (); } kembalikan klien; } / * (non-javadoc) * @see org.apache.commons.pool.objectpool#returnObject (java.lang.object) * / public void returnObject (ftpClient Client) melempar Exception {if (klien! = null) &&! } catch (ioException e) {e.printstacktrace (); }}} public void InvalidateObject (ftpClient Client) melempar Exception {// Hapus Invalidate Client Pool.Remove (Client); } /* (non-Javadoc) * @see org.apache.commons.pool.ObjectPool#addObject() */ public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException { //Insert the object to the queue pool.offer(factory.makeObject(),3,TimeUnit.SECONDS); } public int getNumIdle () melempar UnsupportedOperationException {return 0; } public int getNumActive () melempar UnsupportedOperationException {return 0; } public void clear () melempar Exception, UnsupportedOperationException {} / * (non-javadoc) * @see org.apache.commons.pool.objectpool#close () * / public void close () lemparan pengecualian {while (poolTerator (). hasnext ()) {ftpcclient {while =). factory.destroyObject (klien); }} public void setFactory (poolableObjectFactory <ftpclient> factory) melempar IllegalStateException, UnsupportedOperationException {}}Tulis Implementasi Antarmuka PoolableBjecty Lainnya FTPClientFactory
Impor java.io.ioException; impor org.apache.commons.net.ftp.ftpclient; impor org.apache.commons.net.ftp.ftpreply; impor org.apache.commons.pool.poolableBjecty; impor org.lf4j.logger; impor. com.hdfstoftp.util.ftpClientException;/*** Kelas pabrik ftpClient, memberikan penciptaan dan penghancuran instance ftpClient melalui pabrik ftpclient*@author surga*/public ftpclientfactory mengimplementasikan poolableAbjectory <ftpclient> {ftpclient {prajurit. konfigurasi private ftpClientConfigure; // jeda objek parameter ke pabrik untuk memfasilitasi konfigurasi parameter ftpClient yang relevan ftpClientFactory publik (ftpClientConfigure config) {this.config = config; } / * (non-javadoc) * @see org.apache.commons.pool.poolableObjectFactory#makeObject () * / public ftpclient makeObject () melempar Exception {ftpClient ftpClient = new ftpClient (); ftpClient.setConnectTimeOut (config.getClientTimeOut ()); coba {ftpclient.connect (config.getHost (), config.getport ()); int balasan = ftpclient.getReplycode (); if (! ftpreply.ispositiveCompletion (balasan)) {ftpclient.disconnect (); Logger.warn ("Ftpserver menolak koneksi"); kembali nol; } hasil boolean = ftpClient.login (config.getUserName (), config.getPassword ()); if (! hasil) {lempar ftpClientException baru ("FTPClient Login Gagal! Nama pengguna:" + config.getUserName () + "; kata sandi:" + 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 (); } return ftpClient; } / * (non-javadoc) * @see org.apache.commons.pool.poolableObjectFactory#hancur (java.lang.object) * / public void hancur (ftpclient ftpclient) melempar pengecualian {try {if (ftpclient! = null & null & ftcon (ftpclient & null & null & null & null & null & null (ftpclient & null & null & null & null & null & null & null & null & null (ftpclient! ftpclient.logout (); }} catch (ioException io) {io.printstacktrace (); } akhirnya {// Perhatikan bahwa Anda harus memutuskan koneksi pada kode akhirnya, jika tidak, itu akan menyebabkan koneksi FTP ditempati coba {ftpclient.disconnect (); } catch (ioException io) {io.printstacktrace (); }}} / * (non-javadoc) * @see org.apache.commons.pool.poolableObjectFactory#validateObject (java.lang.object) * / public boolean validateObject (ftpClient ftpClient) {try {return ftpClient.sendnoop (); } catch (ioException e) {lempar runtimeException baru ("gagal memvalidasi klien:" + e, e); }} public void ActivateObject (ftpClient ftpClient) melempar Exception {} public void passiveObject (ftpClient ftpClient) melempar Exception {}}Akhirnya, yang terbaik adalah meneruskan objek parameter ke pabrik untuk memfasilitasi kami untuk menetapkan beberapa parameter ftpClient
paket org.apache.commons.pool.impl.contrib;/** * kelas konfigurasi ftpClient, merangkum konfigurasi yang relevan dari ftpClient * * @author surga */kelas publik ftpClientConfigure {private string host; port int pribadi; nama pengguna string pribadi; kata sandi string pribadi; Private String PassiveMode; Pengkodean string pribadi; Private int ClientTimeout; private int threadnum; Private int TransferFileType; boolean pribadi diganti nama; RetryTimes int pribadi; Public String getHost () {return host; } public void setHost (host string) {this. host = host; } public int getport () {port return; } public void setport (int port) {this. port = port; } string publik getUserName () {return username; } public void setusername (string username) {this. nama pengguna = nama pengguna; } public string getPassword () {return kata sandi; } public void setPassword (kata sandi string) {this. kata sandi = kata sandi; } public string getPassiveMode () {return passiveMode; } public void setPassiveMode (string passiveMode) {this. passiveMode = passiveMode; } public string getEncoding () {return encoding; } public void setencoding (string encoding) {this. encoding = encoding; } public int getClientTimeOut () {return clientTimeOut; } public void setClientTimeOut (int clientTimeout) {this. 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; } public boolean isRenameuploaded () {return renameuploaded; } public void setrenameuploaded (boolean renameuploaded) {this. Renameuploaded = RenameUploaded; } public int getRetRimes () {return retrytimes; } public void setRetryTimes (int retrytimes) {this. retrytimes = retrytimes; } @Override Public String ToString () {return "ftpClientConfig [host =" + host + "/n port =" + port + "/n username =" + nama pengguna + "/n kata sandi =" + kata sandi + "/n passiveMode =" + PASSIVEMODE + "/N Encoding =" + encoding + "/n thepignum; "/n TransferFileType =" + TransferFileType + "/n Renameuploaded =" + RenameUploaded + "/n RetryTimes =" + RetryTimes + "]"; }}Kelas kolam renang FTPClientPool Connection mengelola siklus hidup objek FTPClient, dan bertanggung jawab atas peminjaman, perencanaan, dan penghancuran kolam renang. Kelas FTPClientPool tergantung pada kelas FTPClientFactory, yang digunakan untuk membuat dan menghancurkan objek oleh kelas teknik ini; FTPClientFactory juga bergantung pada kelas FTPClientConfigure, yang bertanggung jawab untuk merangkum parameter konfigurasi FTPClient. Pada titik ini, kumpulan koneksi FTPClient kami telah dikembangkan.
Perlu dicatat bahwa arrayblockingqueue digunakan di FTPClientPool untuk mengelola dan menyimpan objek FTPClient. Untuk memblokir antrian, silakan merujuk ke artikel saya: [Java Concurrency] BlockingQueue
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.