netty Recycler(二)——WeakOrderQueue和Stack

本文通过几个示例程序展示了如何利用Netty中的Recycler在不同线程间进行对象的创建和回收,包括单个和多个对象的处理方式,并介绍了WeakOrderQueue的作用。

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

之前一直搞不清楚WeakOrderQueue的用途,“将别的线程的对象回收到本线程"还是"将别的线程的对象回收到别的线程”(前者是对的)。所以研究了一下

版本一 每个类只回收一个对象

package study.recycler.again;

import io.netty.util.Recycler;

import java.util.concurrent.ConcurrentLinkedQueue;

public class CycliMutiThread {
    private static final Recycler<CyclerA> CyclerRecyclerA = new Recycler<CyclerA>() {
        @Override
        protected CyclerA newObject(Handle<CyclerA> handle) {
            return new CyclerA(handle);
        }
    };
    static final class CyclerA {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerA> handle;
        public CyclerA(Recycler.Handle<CyclerA> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerB> CyclerRecyclerB = new Recycler<CyclerB>() {
        @Override
        protected CyclerB newObject(Handle<CyclerB> handle) {
            return new CyclerB(handle);
        }
    };
    static final class CyclerB {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerB> handle;
        public CyclerB(Recycler.Handle<CyclerB> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerC> CyclerRecyclerC = new Recycler<CyclerC>() {
        @Override
        protected CyclerC newObject(Handle<CyclerC> handle) {
            return new CyclerC(handle);
        }
    };
    static final class CyclerC {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerC> handle;
        public CyclerC(Recycler.Handle<CyclerC> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    public static void  main(String[] args) throws InterruptedException {
        ConcurrentLinkedQueue<CyclerA> q = new ConcurrentLinkedQueue();
        Thread t = Thread.currentThread();
        Thread thread = new Thread(() -> {
            Thread tt = t;
            System.out.println("begin");
            // 1、从回收池获取对象
            CyclerA cycler1 = CyclerRecyclerA.get();
            // 2、开始使用对象
            cycler1.setValue("hello,java");
            // 3、将对象放到队列中
            q.add(cycler1);

            // 4、随便放一个其他对象到回收池中
            CyclerB cyclerB = CyclerRecyclerB.get();
            cyclerB.setValue("cyclerB");
            cyclerB.recycle();

            System.out.println("end");//断点1
        });
        thread.start();
        thread.join();

        CyclerA cycler3 = q.peek();
        // 5、回收对象到对象池
        cycler3.recycle();

        // 6、随便放一个其他对象到回收池中
        CyclerC cyclerC = CyclerRecyclerC.get();
        cyclerC.setValue("cyclerC");
        cyclerC.recycle();
        System.out.println("over");//断点2
    }
}

简要介绍一下程序。CyclerA CyclerB CyclerC是三个可回收的对象。

类名作用
CyclerA一个线程创建,另一个线程回收
CyclerB本线程创建,本线程回收
CyclerC本线程创建,本线程回收

程序运行过程中有两处断点,以在程序的注释中表明

断点1

此时从线程(用new Thread创建的线程姑且叫做从线程,以示区别)回收了CyclerB对象,创建了CyclerA对象

首先在线程的threadLocals成员变量中找到回收池相关对象
在这里插入图片描述
点开可以看到两个stack,一个是CyclerA的回收池,另一个是CyclerB的
在这里插入图片描述

由于CyclerA在这个线程中没有回收,所以elements中没有非空对象
在这里插入图片描述
而CyclerB中有对象
在这里插入图片描述

此时主线程中没有InternalThreadLocalMap这个ThreadLocal
在这里插入图片描述

断点2

此时主线程已经将从线程创建的CyclerA对象回收到本线程中,又回收了自己创建的CyclerC对象

主线程中多出了一个ThreadLocal
在这里插入图片描述
点开这个对象
在这里插入图片描述
上图中有三个对象需要注意
对象1:这个stack是从线程中存储CyclerA所用的对象。(这点可以对比之前截图中的对象编号,都是@758)
对象2:这个WeakOrderQueue是主线程存储CyclerA(由从线程创建)所用的对象
对象3:主线程存储CyclerC

验证对象2
在这里插入图片描述

验证对象3
在这里插入图片描述

此时看从线程,threadLocals字段已经为空
在这里插入图片描述

版本二 同一个线程中回收多个对象

package study.recycler.again;

import io.netty.util.Recycler;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 断点2 主线程回收池中会有大量CyclerA
 */
public class CycliMutiThread5 {
    private static final Recycler<CyclerA> CyclerRecyclerA = new Recycler<CyclerA>() {
        @Override
        protected CyclerA newObject(Handle<CyclerA> handle) {
            return new CyclerA(handle);
        }
    };
    static final class CyclerA {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerA> handle;
        public CyclerA(Recycler.Handle<CyclerA> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerB> CyclerRecyclerB = new Recycler<CyclerB>() {
        @Override
        protected CyclerB newObject(Handle<CyclerB> handle) {
            return new CyclerB(handle);
        }
    };
    static final class CyclerB {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerB> handle;
        public CyclerB(Recycler.Handle<CyclerB> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerC> CyclerRecyclerC = new Recycler<CyclerC>() {
        @Override
        protected CyclerC newObject(Handle<CyclerC> handle) {
            return new CyclerC(handle);
        }
    };
    static final class CyclerC {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerC> handle;
        public CyclerC(Recycler.Handle<CyclerC> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    public static void  main(String[] args) throws InterruptedException {
        ConcurrentLinkedQueue<Object> q = new ConcurrentLinkedQueue();
        Thread t = Thread.currentThread();
        Thread thread = new Thread(() -> {
            Thread tt = t;
            System.out.println("begin");
            // 1、从回收池获取对象
            CyclerA cycler1 = CyclerRecyclerA.get();
            // 2、开始使用对象
            cycler1.setValue("hello,java");
            // 3、将对象放到队列中
            q.add(cycler1);

            // 4、再放一个对象到队列中
            CyclerB cyclerB = CyclerRecyclerB.get();
            cyclerB.setValue("cyclerB");
            q.add(cyclerB);

            System.out.println("end");//断点1
        });
        thread.start();
        thread.join();

        CyclerA cycler3 = (CyclerA) q.poll();
        // 5、回收对象到对象池
        cycler3.recycle();

        CyclerB cycler4 = (CyclerB) q.poll();
        // 5、回收对象到对象池
        cycler4.recycle();

        // 6、随便放一个其他对象到回收池中
        CyclerC cyclerC = CyclerRecyclerC.get();
        cyclerC.setValue("cyclerC");
        cyclerC.recycle();


        List<CyclerA> list = new ArrayList<>();
        for (int i = 0; i < 901; ++i) {
            list.add(CyclerRecyclerA.get());
        }
        for (int i = 0; i < 901; ++i) {
            list.get(i).recycle();
        }
        System.out.println("over");//断点2
    }
}
断点2

在这里插入图片描述
在这里插入图片描述

版本三 不同线程中回收多个对象

package study.recycler.again;

import io.netty.util.Recycler;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 断点2 主线程回收池中会有大量CyclerA
 */
public class CycliMutiThread6 {
    private static final Recycler<CyclerA> CyclerRecyclerA = new Recycler<CyclerA>() {
        @Override
        protected CyclerA newObject(Handle<CyclerA> handle) {
            return new CyclerA(handle);
        }
    };
    static final class CyclerA {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerA> handle;
        public CyclerA(Recycler.Handle<CyclerA> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerB> CyclerRecyclerB = new Recycler<CyclerB>() {
        @Override
        protected CyclerB newObject(Handle<CyclerB> handle) {
            return new CyclerB(handle);
        }
    };
    static final class CyclerB {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerB> handle;
        public CyclerB(Recycler.Handle<CyclerB> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerC> CyclerRecyclerC = new Recycler<CyclerC>() {
        @Override
        protected CyclerC newObject(Handle<CyclerC> handle) {
            return new CyclerC(handle);
        }
    };
    static final class CyclerC {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerC> handle;
        public CyclerC(Recycler.Handle<CyclerC> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    public static void  main(String[] args) throws InterruptedException {
        ConcurrentLinkedQueue<CyclerA> qAThread = new ConcurrentLinkedQueue();
        ConcurrentLinkedQueue<CyclerB> qBThread = new ConcurrentLinkedQueue();
        ConcurrentLinkedQueue<CyclerA> qAThread1 = new ConcurrentLinkedQueue();
        ConcurrentLinkedQueue<CyclerB> qBThread1 = new ConcurrentLinkedQueue();
        Thread t = Thread.currentThread();
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 901; ++i) {
                CyclerA cyclerA = CyclerRecyclerA.get();
                qAThread.add(cyclerA);
            }
            for (int i = 0; i < 901; ++i) {
                CyclerB cyclerB = CyclerRecyclerB.get();
                qBThread.add(cyclerB);
            }
        });
        thread.start();
        thread.join();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 901; ++i) {
                CyclerA cyclerA = CyclerRecyclerA.get();
                qAThread1.add(cyclerA);
            }
            for (int i = 0; i < 901; ++i) {
                CyclerB cyclerB = CyclerRecyclerB.get();
                qBThread1.add(cyclerB);
            }
        });
        thread1.start();
        thread1.join();

        for (int i = 0; i < 901; ++i) {
            CyclerA poll = qAThread.poll();
            poll.recycle();
        }

        for (int i = 0; i < 901; ++i) {
            CyclerB poll = qBThread.poll();
            poll.recycle();
        }

        for (int i = 0; i < 901; ++i) {
            CyclerA poll = qAThread1.poll();
            poll.recycle();
        }

        for (int i = 0; i < 901; ++i) {
            CyclerB poll = qBThread1.poll();
            poll.recycle();
        }

        System.out.println("over");//断点2
    }
}

主线程中启动了两个线程,每个线程中都用回收池创建了大量的CyclerA CyclerB对象

断点2

在这里插入图片描述

以下面这个举例,对象为CyclerB
在这里插入图片描述
若想看属于哪个线程
在这里插入图片描述

换一个再看看
在这里插入图片描述

在这里插入图片描述

上面两张图展示的是另一个线程的CyclerA对象

多个线程回收主线程创建的对象
package study.recycler.again;

import io.netty.util.Recycler;

import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 断点2 主线程回收池中会有大量CyclerA
 */
public class CycliMutiThread7 {
    private static final Recycler<CyclerA> CyclerRecyclerA = new Recycler<CyclerA>() {
        @Override
        protected CyclerA newObject(Handle<CyclerA> handle) {
            return new CyclerA(handle);
        }
    };
    static final class CyclerA {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerA> handle;
        public CyclerA(Recycler.Handle<CyclerA> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerB> CyclerRecyclerB = new Recycler<CyclerB>() {
        @Override
        protected CyclerB newObject(Handle<CyclerB> handle) {
            return new CyclerB(handle);
        }
    };
    static final class CyclerB {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerB> handle;
        public CyclerB(Recycler.Handle<CyclerB> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    private static final Recycler<CyclerC> CyclerRecyclerC = new Recycler<CyclerC>() {
        @Override
        protected CyclerC newObject(Handle<CyclerC> handle) {
            return new CyclerC(handle);
        }
    };
    static final class CyclerC {
        private String value;
        public void setValue(String value) {
            this.value = value;
        }
        private Recycler.Handle<CyclerC> handle;
        public CyclerC(Recycler.Handle<CyclerC> handle) {
            this.handle = handle;
        }
        public void recycle() {
            handle.recycle(this);
        }
    }
    public static void  main(String[] args) throws InterruptedException {
        ConcurrentLinkedQueue<CyclerA> qAThread = new ConcurrentLinkedQueue();
        Thread t = Thread.currentThread();

        for (int i = 0; i < 901; ++i) {
            qAThread.add(CyclerRecyclerA.get());
        }

        Thread t1 = new Thread(() -> {
            CyclerA cyclerA = qAThread.poll();
            cyclerA.setValue("t1");
            cyclerA.recycle();
        });

        Thread t2 = new Thread(() -> {
            CyclerA cyclerA = qAThread.poll();
            cyclerA.setValue("t2");
            cyclerA.recycle();
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();


        System.out.println("over");//断点2
    }
}

在这里插入图片描述

上面截图的节构对应着下图
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值