JavaRush /Kurslar /All lectures for UZ purposes /Thread Pool bilan ishlash

Thread Pool bilan ishlash

All lectures for UZ purposes
Daraja, Dars
Mavjud

7.1 Connection pool

Bugun biz ma'lumotlar bazasi bilan yanada professional tarzda ishlashni o'rganamiz. Va endi biz connection pool haqida so'zlab beramiz.

Ma'lumotlar bazasiga ulanish ma'lum vaqtni talab qiladi. Xususan, agar ma'lumotlar bazasi uzoqda joylashgan bo'lsa. Har bir so'rov uchun ma'lumotlar bazasiga ulanish qilish kerak bo'lsa, dasturning javob tezligi juda past bo'ladi. Foydalanadigan resurslarni aytmasak ham bo'ladi.

Bunday muammolarni hal qilish uchun ma'lum bir to'plamda ma'lumotlar bazasiga ulanishlarni saqlash taklif etilgan, bu to'plam thread pool deb ataladi.

Yangi ulanish so'raganda, connection pool uni yaratadi, lekin yopishda uni yopmaydi, balki connection pool’da saqlaydi. Agar biz yana connection pool’dan ulanish so'rasak, u yangi yaratmasdan, eski ulanishlardan birini beradi.

Dastur asosan connection pool bilan ishlash funksionaliga ega bo'lgan maxsus driver orqali ishlaydi. Bu vaziyatni quyidagi rasmda tasvirlash mumkin:

Programmaer pool ulanishlarini sozlashlari mumkin: faol ulanishlar soni, kutish vaqti va boshqalar.

Juda ekstremal holatlar uchun, o'z connection pool’ni yozish mumkin: bu class, ulanishlar ro'yxatiga ega bo'ladi va unda close funksiyasi qayta aniqlanadi, ulanishni ro'yxatga qaytarib beradi, va boshqa ko'plab foydali funksiyalar qo'shiladi, masalan ochiq ulanishning vaqti. Agar ulanish uzoq vaqt ishlatilmasa, ulanish yopiladi.

7.2* DataSource va ConnectionPoolDataSource interfeyslari

Thread pool odatda DataSource obyekti bilan birgalikda ishlaydi. Bu ob'ekt ma'lumotlar bazasining bir turi abstraktsiyasi sifatida ko'rilishi mumkin. Data Source nomi aynan Ma'lumot manbai deb tarjima qilinadi, ya'ni ma'lumotli qilib ko'rsatadi.

DataSource ob'ektlari ma'lumotlar bazasi bilan jismoniy ulanish olish uchun ishlatiladi va DriverManager’ga alternativ hisoblanadi. JDBC-driverni ro'yxatdan o'tkazish shart emas. Faqat ulanishni o'rnatish uchun tegishli parametrlarni belgilash va getConnection() metodini bajaring.

DataSource tipidagi obyekt lokal tarzda yaratilganda (to'g'ridan-to'g'ri dasturda), ulanish parametrlarini JDBC-driver yetkazib beruvchisi tomonidan taqdim etilgan tegishli metodlar orqali belgilash mumkin. Bu metodlar DataSource interfeysida aniqlanmagan, chunki har xil ishlab chiqaruvchilarning ma'lumotlar bazasi bilan ulanish parametrlarining turi va soni farq qilishi mumkin (masalan, barcha ma'lumotlar bazalari uchun driver turi yoki tarmoq protokoli ko'rsatilishi zarur emas).

Masalan, Oracle ma'lumotlar bazasi bilan ishlashda tegishli set va get metodlaridan foydalanish uchun OracleDataSource tipidagi obyektni olish kerak, bu class DataSource interfeysini amalga oshiradi. Shuning uchun DataSource tipidagi ob'ektlarni yaratish usuli kodingizni ancha kam ajratiladigan va driverning konkret realizatsiyasiga bog'liq qilib qo'yadi.

Quyida DataSource tipidagi obyektlarning lokal ishlatilishini ko'rsatuvchi kod misoli keltirilgan.


import java.sql.*;
import javax.sql.*;
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.*;
 
public class DataSource {
    public static void main(String[] args) {
    	try {
        	OracleDataSource ods = new OracleDataSource();
        	
        	ods.setUser("root"); // Foydalanuvchi nomi
        	ods.setPassword("secret"); // Parol
        	ods.setDriverType("thin"); // Driver turi
        	ods.setDatabaseName("test"); // Ma'lumotlar bazasi nomi
        	ods.setServerName("localhost"); // Server nomi
        	ods.setPortNumber(1521); // Port raqami
        	
        	Connection connection = ods.getConnection();
        	System.out.println("Ulanish muvaffaqiyatli!!!");
        	
    	} catch (SQLException se) {
        	se.printStackTrace();
    	}
    	System.out.println("Xayr!");
	}  
}

7.3* JNDI interfeysi

DataSource tipidagi ob'ektlar butun imkoniyatlarini JNDI interfeysi bilan birgalikda foydalanishda namoyon etadi. JNDI — bu katta server dasturlar uchun maxsus servis (bir turdagi katalog), bu bir servisga boshqa servislarga ulanishni osonlashtiradi.

Nomi va katalog xizmati, tizim administrator tomonidan oldindan yaratilgan, DataSource tipidagi ob'ektlarni oldindan tuzilgan ulanish parametrlar bilan saqlash imkonini beradi. Quyida Sun kompaniyasi tomonidan ishlab chiqilgan ba'zi standart mulk nomlari (parametrlar) keltirilgan:

Mulk nomi Java ma'lumotlar turi Maqsad
databaseName String Ma'lumotlar bazasi nomi
serverName String Server nomi
user String Foydalanuvchi nomi (ID)
password String Foydalanuvchi paroli
portNumber Int DBMS server port raqami

DataSource va JNDI interfeyslarining birgalikda ishlatilishi ko‘p darajali korporativ dasturlarni, J2EE komponent texnologiyaga asoslangan rivojlantirishda hal qiluvchi rol o'ynaydi.

DataSource va JNDI interfeyslarining kombinatsiyasidan foydalanganda, dasturning kodida faqat DataSource tipidagi ob'ektni nomlar va kataloglar xizmatidan talab qilish kerak bo'ladi. Shu bilan birga, ulanish tafsilotlari va konkret driver realizatsiyasiga bog'liq dastur kodi dasturni xizmatda va kataloglar ob'yektivda saqlanib qolganining orqasida yashiringan bo'ladi.

DataSource va JNDI tipidagi ob'ektlarni birgalikda foydalanish, ikki mustaqil bajariladigan bosqichlarning mavjudligini anglatadi:

  1. DataSource tipidagi nomlanuvchi ob'ektni nomlar va kataloglar xizmatida saqlash kerak, javax.naming paketning Context.bind() metodidan foydalanib.
  2. Nomlar va kataloglar xizmatidan DataSource tipidagi ob'ektni dasturning talabiga binoan olish kerak, Context.lookup() metodidan foydalanib. Shundan so‘ng, ma'lumotlar bazasiga ulanish olish uchun DataSource.getConnection() metodidan foydalanish mumkin.

Quyida JNDI interfeysi va OracleDataSource tipidagi ob'yektning birgalikda ishlatilish misoli keltirilgan.


// JNDI asosiy ob'ektni yaratamiz
Hashtable env = new Hashtable();
env.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put (Context.PROVIDER_URL, "file:JNDI");
Context ctx = new InitialContext(env);
 
// DataSource ob'ektini nomiga qarab olamiz
DataSource ods = (DataSource) ctx.lookup("myDatabase");
 
// DataSource ob'ektidan Connection olamiz
Connection connection = ods.getConnection();
System.out.println("Ulanish muvaffaqiyatli!!!");

JNDI ishlashini biz ko'rib chiqmaymiz. Bu kursning doirasidan chiqadi. Faqat bilishni xohlardim, bu yondashuv katta dasturlarda juda ko'p qo'llaniladi. Kelajakda bunday kodni ko'rsangiz hayron bo'lmang.

Bu qanday ishlashi muhim emas. Sizga shunchaki JNDI xizmati orqali xizmatlar katalogida ro'yxatdan o'tgan har qanday xizmatni proxy-ob'ektini olish mumkinligini bilishingiz kerak. Aynan shu tarzda DataSource ob'ekti olinib, ma'lumotlar bazasi bilan ishlanadi.

7.4 Connection Pool’lar misollari

Keling, yaxshisi boshlaganimizni davom ettiramiz— connection pool’lar haqida gaplashamiz.

Java dasturchilar o‘z dasturlarida connection pool’larning turli xil implementatsiyalari mavjud kutubxonalardan juda ko‘p foydalanadilar. Ular orasida uchta eng mashhuri:

  • Apache Commons DBCP
  • C3PO
  • HikariCP

Birinchi bo'lib yaxshi connection poolni Apache loyihasining dasturchilari yaratdi, u ham Tomcat veb-serverida ishlatiladi. U bilan qanday ishlash mumkinligi:


public class DBCPDataSource {
 
    private static BasicDataSource ds = new BasicDataSource();
    static {
    	ds.setUrl("jdbc:h2:mem:test");
    	ds.setUsername("user");
    	ds.setPassword("password");
    	ds.setMinIdle(5);
    	ds.setMaxIdle(10);
    	ds.setMaxOpenPreparedStatements(100);
    }
   
    public static Connection getConnection() throws SQLException {
    	return ds.getConnection();
    }
   
    private DBCPDataSource(){ }
}

Ikkinchi juda mashhur pool — bu C3PO. G'alati nomlar, to'g'ri? C3PO nomi — Yulduzli Urushlar filmlaridagi C3PO robotining nomiga ishora. Va CP — bu Connection Pool’ning qisqartmasi.


public class C3p0DataSource {
 
    private static ComboPooledDataSource cpds = new ComboPooledDataSource();
    static {
    	try {
        	cpds.setDriverClass("org.h2.Driver");
        	cpds.setJdbcUrl("jdbc:h2:mem:test");
        	cpds.setUser("user");
        	cpds.setPassword("password");
    	} catch (PropertyVetoException e) {
            // xatoni hal qiling
    	}
    }
  
    public static Connection getConnection() throws SQLException {
    	return cpds.getConnection();
    }
  
    private C3p0DataSource(){}
}

Uning hujjatlari bilan rasmiy sahifasida tanishish mumkin.

Va nihoyat, hozirgi davrning eng mashhur Connection Pool’laridan biri bu HikariCP:


public class HikariCPDataSource {
   
    private static HikariConfig config = new HikariConfig();
    private static HikariDataSource ds;
   
    static {
    	config.setJdbcUrl("jdbc:h2:mem:test");
    	config.setUsername("user");
    	config.setPassword("password");
    	config.addDataSourceProperty("cachePrepStmts", "true");
    	config.addDataSourceProperty("prepStmtCacheSize", "250");
    	config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    	ds = new HikariDataSource(config);
    }
   
    public static Connection getConnection() throws SQLException {
    	return ds.getConnection();
    }
   
    private HikariCPDataSource(){}
}

Bu yerda uning GitHub’dagi rasmiy sahifasi.

Va konfiguratsiyasi haqidagi yaxshi maqola.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION