之前一直搞不清楚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
}
}
上面截图的节构对应着下图