Native Code To Gget Expensive Resource Such As Database Connection(Self Protection Mechanism)

本文介绍了一种资源池模型,用于在高并发场景中有效管理和保护系统资源,如数据库连接。通过动态代理创建资源实例,使用资源池类实现资源的获取和释放,确保在资源有限的情况下,线程能及时响应并避免长时间等待。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

emm, in our common application scenario, getting system resource such as database connection seems to be easy , but when we program in high concurrent scenario , it would be disorder. How can we protect our rare and precious system resources? I think this model may help us:

ResourcePool -> the main Class

public class ResourcePool {

    private LinkedList<Resource> pool = new LinkedList<>();

    public ResourcePool(int initialSize) {
        if(initialSize > 0){
            for (int i = 0; i < initialSize; i++) {
                pool.addLast(ResourceDriver.createResource());
            }
        }
    }


    public void releaseResource(Resource resource){
        if(resource != null){
            synchronized (pool){ //after jdk 1.6 I prefer use synchronized to ConcurrentLinkedQueue
                pool.addLast(resource);
                pool.notifyAll();
            }
        }
    }

    public Resource fetchResource(long mills) throws InterruptedException {
        synchronized (pool){
            //full time out
            if(mills < 0){
                while(pool.isEmpty()){
                    pool.wait();
                }
                return pool.removeFirst();
            }else {
                long future = System.currentTimeMillis() + mills;
                long remaining = mills;
                while(pool.isEmpty() && remaining > 0){
                    pool.wait(remaining);
                    remaining = future - System.currentTimeMillis();
                }
                Resource resource = null;//you can implement a NullAble resources
                if(!pool.isEmpty())
                    resource = pool.removeFirst();
                return  resource;
            }

        }
    }


}

Class To Construct Resource : for convenienceuse, use dynamic proxy to construct resource instance
//in your code, you can implement your realistic service

mport java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;

/**
 * Created by LY on 2018/11/30.
 */
public class ResourceDriver {

    static class ResourceHandler implements InvocationHandler{
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if(method.getName().equals("commit")){
                TimeUnit.MILLISECONDS.sleep(100);//mock do some service
            }
            return null;
        }
    }

    public static final Resource createResource(){
        return (Resource) Proxy.newProxyInstance(ResourceDriver.class.getClassLoader(),
                new Class<?>[] {Resource.class}, new ResourceHandler());
    }
}

Resource://alright, here you can use Nullable model to protect your system from occurred NullPointException …you can see my blog to use Nullable model

/**
 * Created by LY on 2018/11/30.
 */
public interface Resource {
    public void commit();
}

the test code–>

public class test  {

    static ResourcePool pool = new ResourcePool(10);
    //make all thread start together
    static CountDownLatch start = new CountDownLatch(1);
    static CountDownLatch end;

    public static void main(String[] args) throws InterruptedException {
        int threadCount = 100;
        end = new CountDownLatch(threadCount);
        int count = 20;
        AtomicInteger got = new AtomicInteger();
        AtomicInteger nogot = new AtomicInteger();
        for(int i = 0; i < threadCount; i++){
            Thread thread = new Thread(new ResourceRunner(count,got,nogot),"testThread");
            thread.start();
        }
        start.countDown();
        end.await();//wait all thread do task
        System.out.println("total invoke: " + threadCount*count);
        System.out.println("got Resources: " + got);
        System.out.println("no got Resources: " + nogot);
    }


    static class ResourceRunner implements Runnable {
        int count;
        AtomicInteger got;
        AtomicInteger nogot;
        public ResourceRunner(int count, AtomicInteger got, AtomicInteger nogot) {
            this.count = count;
            this.got = got;
            this.nogot = nogot;
        }

        @Override
        public void run() {
            try {
                start.await();
            }catch (Exception e){

            }
            while(count > 0){
                try{
                    Resource resource = pool.fetchResource(1000);
                    if(resource != null){
                        try {
                            resource.commit();
                        }finally {
                            pool.releaseResource(resource);
                            got.incrementAndGet();
                        }
                    }else {
                        nogot.incrementAndGet();
                    }
                }catch (Exception e1){
                }finally {
                    count--;
                }
            }
            end.countDown();
        }

    }
}

we only has 10 Resource instance,

when the thread count is 10,the result is
–total invoke: 200
–got Resources: 200
–no got Resources: 0

when the thread count is 50,the result is
–total invoke: 1000
–got Resources: 816
–no got Resources: 184

when the thread count is 100,the result is
–total invoke: 2000
–got Resources: 1291
–no got Resources: 709

(my mechine is CPU i5-4210M, 4G memory)

中文总结:虽然客户端在这种超时获取的操作下会出现连接无法获取的情况,但是它能够保证客户端线程不会一直挂在连接获取的操作上,而是按时返回,并告知客户端连接获取出现问题,是系统的一种自我保护机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值