Hide Recycler implemention to allow experimenting with different implementions of an Object pool (#9715)

Motivation:

At the moment we directly extend the Recycler base class in our code which makes it hard to experiment with different Object pool implementation. It would be nice to be able to switch from one to another by using a system property in the future. This would also allow to more easily test things like https://github.com/netty/netty/pull/8052.

Modifications:

- Introduce ObjectPool class with static method that we now use internally to obtain an ObjectPool implementation.
- Wrap the Recycler into an ObjectPool and return it for now

Result:

Preparation for different ObjectPool implementations
This commit is contained in:
Norman Maurer 2019-10-26 00:34:30 -07:00
parent 77accfcc53
commit 4be554a21f
18 changed files with 204 additions and 91 deletions

View File

@ -16,8 +16,8 @@
package io.netty.buffer;
import io.netty.util.Recycler.Handle;
import io.netty.util.ReferenceCounted;
import io.netty.util.internal.ObjectPool.Handle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

View File

@ -18,10 +18,11 @@ package io.netty.buffer;
import io.netty.util.AsciiString;
import io.netty.util.ByteProcessor;
import io.netty.util.CharsetUtil;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.MathUtil;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil;
import io.netty.util.internal.SystemPropertyUtil;
@ -1171,13 +1172,13 @@ public final class ByteBufUtil {
static final class ThreadLocalUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf {
private static final Recycler<ThreadLocalUnsafeDirectByteBuf> RECYCLER =
new Recycler<ThreadLocalUnsafeDirectByteBuf>() {
private static final ObjectPool<ThreadLocalUnsafeDirectByteBuf> RECYCLER =
ObjectPool.newPool(new ObjectCreator<ThreadLocalUnsafeDirectByteBuf>() {
@Override
protected ThreadLocalUnsafeDirectByteBuf newObject(Handle<ThreadLocalUnsafeDirectByteBuf> handle) {
public ThreadLocalUnsafeDirectByteBuf newObject(Handle<ThreadLocalUnsafeDirectByteBuf> handle) {
return new ThreadLocalUnsafeDirectByteBuf(handle);
}
};
});
static ThreadLocalUnsafeDirectByteBuf newInstance() {
ThreadLocalUnsafeDirectByteBuf buf = RECYCLER.get();
@ -1205,12 +1206,13 @@ public final class ByteBufUtil {
static final class ThreadLocalDirectByteBuf extends UnpooledDirectByteBuf {
private static final Recycler<ThreadLocalDirectByteBuf> RECYCLER = new Recycler<ThreadLocalDirectByteBuf>() {
private static final ObjectPool<ThreadLocalDirectByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<ThreadLocalDirectByteBuf>() {
@Override
protected ThreadLocalDirectByteBuf newObject(Handle<ThreadLocalDirectByteBuf> handle) {
public ThreadLocalDirectByteBuf newObject(Handle<ThreadLocalDirectByteBuf> handle) {
return new ThreadLocalDirectByteBuf(handle);
}
};
});
static ThreadLocalDirectByteBuf newInstance() {
ThreadLocalDirectByteBuf buf = RECYCLER.get();

View File

@ -20,9 +20,10 @@ package io.netty.buffer;
import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
import io.netty.buffer.PoolArena.SizeClass;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.MathUtil;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -492,12 +493,12 @@ final class PoolThreadCache {
}
@SuppressWarnings("rawtypes")
private static final Recycler<Entry> RECYCLER = new Recycler<Entry>() {
private static final ObjectPool<Entry> RECYCLER = ObjectPool.newPool(new ObjectCreator<Entry>() {
@SuppressWarnings("unchecked")
@Override
protected Entry newObject(Handle<Entry> handle) {
public Entry newObject(Handle<Entry> handle) {
return new Entry(handle);
}
};
});
}
}

View File

@ -16,8 +16,7 @@
package io.netty.buffer;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.ObjectPool.Handle;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -29,7 +28,7 @@ import java.nio.channels.ScatteringByteChannel;
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
private final Recycler.Handle<PooledByteBuf<T>> recyclerHandle;
private final Handle<PooledByteBuf<T>> recyclerHandle;
protected PoolChunk<T> chunk;
protected long handle;
@ -42,7 +41,7 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
private ByteBufAllocator allocator;
@SuppressWarnings("unchecked")
protected PooledByteBuf(Recycler.Handle<? extends PooledByteBuf<T>> recyclerHandle, int maxCapacity) {
protected PooledByteBuf(Handle<? extends PooledByteBuf<T>> recyclerHandle, int maxCapacity) {
super(maxCapacity);
this.recyclerHandle = (Handle<PooledByteBuf<T>>) recyclerHandle;
}

View File

@ -16,7 +16,9 @@
package io.netty.buffer;
import io.netty.util.Recycler;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import java.io.IOException;
import java.io.InputStream;
@ -25,12 +27,13 @@ import java.nio.ByteBuffer;
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
private static final ObjectPool<PooledDirectByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledDirectByteBuf>() {
@Override
protected PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
public PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
return new PooledDirectByteBuf(handle, 0);
}
};
});
static PooledDirectByteBuf newInstance(int maxCapacity) {
PooledDirectByteBuf buf = RECYCLER.get();
@ -38,7 +41,7 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
return buf;
}
private PooledDirectByteBuf(Recycler.Handle<PooledDirectByteBuf> recyclerHandle, int maxCapacity) {
private PooledDirectByteBuf(Handle<PooledDirectByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity);
}

View File

@ -17,8 +17,9 @@
package io.netty.buffer;
import io.netty.util.ByteProcessor;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import java.io.IOException;
import java.io.InputStream;
@ -30,12 +31,13 @@ import java.nio.channels.ScatteringByteChannel;
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf {
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
private static final ObjectPool<PooledDuplicatedByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledDuplicatedByteBuf>() {
@Override
protected PooledDuplicatedByteBuf newObject(Handle<PooledDuplicatedByteBuf> handle) {
public PooledDuplicatedByteBuf newObject(Handle<PooledDuplicatedByteBuf> handle) {
return new PooledDuplicatedByteBuf(handle);
}
};
});
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
int readerIndex, int writerIndex) {

View File

@ -14,7 +14,9 @@
package io.netty.buffer;
import io.netty.util.Recycler;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PlatformDependent;
import java.io.IOException;
@ -24,12 +26,13 @@ import java.nio.ByteBuffer;
class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
private static final ObjectPool<PooledHeapByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledHeapByteBuf>() {
@Override
protected PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
public PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
return new PooledHeapByteBuf(handle, 0);
}
};
});
static PooledHeapByteBuf newInstance(int maxCapacity) {
PooledHeapByteBuf buf = RECYCLER.get();
@ -37,7 +40,7 @@ class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
return buf;
}
PooledHeapByteBuf(Recycler.Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
PooledHeapByteBuf(Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity);
}

View File

@ -17,8 +17,9 @@
package io.netty.buffer;
import io.netty.util.ByteProcessor;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import java.io.IOException;
import java.io.InputStream;
@ -32,12 +33,13 @@ import static io.netty.buffer.AbstractUnpooledSlicedByteBuf.checkSliceOutOfBound
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf {
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
private static final ObjectPool<PooledSlicedByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledSlicedByteBuf>() {
@Override
protected PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
public PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
return new PooledSlicedByteBuf(handle);
}
};
});
static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
int index, int length) {

View File

@ -16,7 +16,9 @@
package io.netty.buffer;
import io.netty.util.Recycler;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PlatformDependent;
import java.io.IOException;
@ -25,12 +27,13 @@ import java.io.OutputStream;
import java.nio.ByteBuffer;
final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
private static final ObjectPool<PooledUnsafeDirectByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledUnsafeDirectByteBuf>() {
@Override
protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
public PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
return new PooledUnsafeDirectByteBuf(handle, 0);
}
};
});
static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
PooledUnsafeDirectByteBuf buf = RECYCLER.get();
@ -40,7 +43,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private long memoryAddress;
private PooledUnsafeDirectByteBuf(Recycler.Handle<PooledUnsafeDirectByteBuf> recyclerHandle, int maxCapacity) {
private PooledUnsafeDirectByteBuf(Handle<PooledUnsafeDirectByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity);
}

View File

@ -15,18 +15,20 @@
*/
package io.netty.buffer;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PlatformDependent;
final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf {
private static final Recycler<PooledUnsafeHeapByteBuf> RECYCLER = new Recycler<PooledUnsafeHeapByteBuf>() {
private static final ObjectPool<PooledUnsafeHeapByteBuf> RECYCLER = ObjectPool.newPool(
new ObjectCreator<PooledUnsafeHeapByteBuf>() {
@Override
protected PooledUnsafeHeapByteBuf newObject(Handle<PooledUnsafeHeapByteBuf> handle) {
public PooledUnsafeHeapByteBuf newObject(Handle<PooledUnsafeHeapByteBuf> handle) {
return new PooledUnsafeHeapByteBuf(handle, 0);
}
};
});
static PooledUnsafeHeapByteBuf newUnsafeInstance(int maxCapacity) {
PooledUnsafeHeapByteBuf buf = RECYCLER.get();

View File

@ -17,6 +17,7 @@
package io.netty.util;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -191,9 +192,7 @@ public abstract class Recycler<T> {
protected abstract T newObject(Handle<T> handle);
public interface Handle<T> {
void recycle(T object);
}
public interface Handle<T> extends ObjectPool.Handle<T> { }
static final class DefaultHandle<T> implements Handle<T> {
private int lastRecycledId;

View File

@ -0,0 +1,89 @@
/*
* Copyright 2019 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.util.internal;
import io.netty.util.Recycler;
/**
* Light-weight object pool.
*
* @param <T> the type of the pooled object
*/
public abstract class ObjectPool<T> {
ObjectPool() { }
/**
* Get a {@link Object} from the {@link ObjectPool}. The returned {@link Object} may be created via
* {@link ObjectCreator#newObject(Handle)} if no pooled {@link Object} is ready to be reused.
*/
public abstract T get();
/**
* Handle for an pooled {@link Object} that will be used to notify the {@link ObjectPool} once it can
* reuse the pooled {@link Object} again.
* @param <T>
*/
public interface Handle<T> {
/**
* Recycle the {@link Object} if possible and so make it ready to be reused.
*/
void recycle(T self);
}
/**
* Creates a new Object which references the given {@link Handle} and calls {@link Handle#recycle(Object)} once
* it can be re-used.
*
* @param <T> the type of the pooled object
*/
public interface ObjectCreator<T> {
/**
* Creates an returns a new {@link Object} that can be used and later recycled via
* {@link Handle#recycle(Object)}.
*/
T newObject(Handle<T> handle);
}
/**
* Creates a new {@link ObjectPool} which will use the given {@link ObjectCreator} to create the {@link Object}
* that should be pooled.
*/
public static <T> ObjectPool<T> newPool(final ObjectCreator<T> creator) {
ObjectUtil.checkNotNull(creator, "creator");
return new RecyclerObjectPool<T>(creator);
}
private static final class RecyclerObjectPool<T> extends ObjectPool<T> {
private final Recycler<T> recycler;
RecyclerObjectPool(final ObjectCreator<T> creator) {
recycler = new Recycler<T>() {
@Override
protected T newObject(Handle<T> handle) {
return creator.newObject(handle);
}
};
}
@Override
public T get() {
return recycler.get();
}
}
}

View File

@ -15,20 +15,21 @@
*/
package io.netty.util.internal;
import io.netty.util.Recycler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
/**
* Some pending write which should be picked up later.
*/
public final class PendingWrite {
private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() {
private static final ObjectPool<PendingWrite> RECYCLER = ObjectPool.newPool(new ObjectCreator<PendingWrite>() {
@Override
protected PendingWrite newObject(Handle<PendingWrite> handle) {
public PendingWrite newObject(Handle<PendingWrite> handle) {
return new PendingWrite(handle);
}
};
});
/**
* Create a new empty {@link RecyclableArrayList} instance
@ -40,11 +41,11 @@ public final class PendingWrite {
return pending;
}
private final Recycler.Handle<PendingWrite> handle;
private final Handle<PendingWrite> handle;
private Object msg;
private Promise<Void> promise;
private PendingWrite(Recycler.Handle<PendingWrite> handle) {
private PendingWrite(Handle<PendingWrite> handle) {
this.handle = handle;
}

View File

@ -18,8 +18,8 @@ package io.netty.util.internal;
import static java.util.Objects.requireNonNull;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import java.util.ArrayList;
import java.util.Collection;
@ -35,12 +35,13 @@ public final class RecyclableArrayList extends ArrayList<Object> {
private static final int DEFAULT_INITIAL_CAPACITY = 8;
private static final Recycler<RecyclableArrayList> RECYCLER = new Recycler<RecyclableArrayList>() {
private static final ObjectPool<RecyclableArrayList> RECYCLER = ObjectPool.newPool(
new ObjectCreator<RecyclableArrayList>() {
@Override
protected RecyclableArrayList newObject(Handle<RecyclableArrayList> handle) {
public RecyclableArrayList newObject(Handle<RecyclableArrayList> handle) {
return new RecyclableArrayList(handle);
}
};
});
private boolean insertSinceRecycled;

View File

@ -23,9 +23,10 @@ import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -216,12 +217,13 @@ public class FlowControlHandler implements ChannelHandler {
*/
private static final int DEFAULT_NUM_ELEMENTS = 2;
private static final Recycler<RecyclableArrayDeque> RECYCLER = new Recycler<RecyclableArrayDeque>() {
private static final ObjectPool<RecyclableArrayDeque> RECYCLER = ObjectPool.newPool(
new ObjectCreator<RecyclableArrayDeque>() {
@Override
protected RecyclableArrayDeque newObject(Handle<RecyclableArrayDeque> handle) {
public RecyclableArrayDeque newObject(Handle<RecyclableArrayDeque> handle) {
return new RecyclableArrayDeque(DEFAULT_NUM_ELEMENTS, handle);
}
};
});
public static RecyclableArrayDeque newInstance() {
return RECYCLER.get();

View File

@ -19,11 +19,12 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.InternalThreadLocalMap;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.Handle;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.PromiseNotificationUtil;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
@ -787,12 +788,12 @@ public final class ChannelOutboundBuffer {
}
static final class Entry {
private static final Recycler<Entry> RECYCLER = new Recycler<Entry>() {
private static final ObjectPool<Entry> RECYCLER = ObjectPool.newPool(new ObjectCreator<Entry>() {
@Override
protected Entry newObject(Handle<Entry> handle) {
public Entry newObject(Handle<Entry> handle) {
return new Entry(handle);
}
};
});
private final Handle<Entry> handle;
Entry next;

View File

@ -20,10 +20,10 @@ import static java.util.Objects.requireNonNull;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.Recycler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.ResourceLeakHint;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.PromiseNotificationUtil;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.StringUtil;
@ -1175,15 +1175,15 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
abstract static class AbstractWriteTask implements Runnable {
private final Recycler.Handle<AbstractWriteTask> handle;
private final ObjectPool.Handle<AbstractWriteTask> handle;
private DefaultChannelHandlerContext ctx;
private Object msg;
private ChannelPromise promise;
private int size;
@SuppressWarnings("unchecked")
private AbstractWriteTask(Recycler.Handle<? extends AbstractWriteTask> handle) {
this.handle = (Recycler.Handle<AbstractWriteTask>) handle;
private AbstractWriteTask(ObjectPool.Handle<? extends AbstractWriteTask> handle) {
this.handle = (ObjectPool.Handle<AbstractWriteTask>) handle;
}
protected static void init(AbstractWriteTask task, DefaultChannelHandlerContext ctx,
@ -1241,12 +1241,13 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
static final class WriteTask extends AbstractWriteTask implements SingleThreadEventLoop.NonWakeupRunnable {
private static final Recycler<WriteTask> RECYCLER = new Recycler<WriteTask>() {
private static final ObjectPool<WriteTask> RECYCLER = ObjectPool.newPool(
new ObjectPool.ObjectCreator<WriteTask>() {
@Override
protected WriteTask newObject(Handle<WriteTask> handle) {
public WriteTask newObject(ObjectPool.Handle<WriteTask> handle) {
return new WriteTask(handle);
}
};
});
static WriteTask newInstance(
DefaultChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
@ -1260,19 +1261,20 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
return ctx.findContextOutbound(MASK_WRITE);
}
private WriteTask(Recycler.Handle<WriteTask> handle) {
private WriteTask(ObjectPool.Handle<WriteTask> handle) {
super(handle);
}
}
static final class WriteAndFlushTask extends AbstractWriteTask {
private static final Recycler<WriteAndFlushTask> RECYCLER = new Recycler<WriteAndFlushTask>() {
private static final ObjectPool<WriteAndFlushTask> RECYCLER = ObjectPool.newPool(
new ObjectPool.ObjectCreator<WriteAndFlushTask>() {
@Override
protected WriteAndFlushTask newObject(Handle<WriteAndFlushTask> handle) {
public WriteAndFlushTask newObject(ObjectPool.Handle<WriteAndFlushTask> handle) {
return new WriteAndFlushTask(handle);
}
};
});
static WriteAndFlushTask newInstance(
DefaultChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
@ -1281,7 +1283,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
return task;
}
private WriteAndFlushTask(Recycler.Handle<WriteAndFlushTask> handle) {
private WriteAndFlushTask(ObjectPool.Handle<WriteAndFlushTask> handle) {
super(handle);
}

View File

@ -17,9 +17,10 @@ package io.netty.channel;
import static java.util.Objects.requireNonNull;
import io.netty.util.Recycler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.PromiseCombiner;
import io.netty.util.internal.ObjectPool;
import io.netty.util.internal.ObjectPool.ObjectCreator;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -285,20 +286,20 @@ public final class PendingWriteQueue {
* Holds all meta-data and construct the linked-list structure.
*/
static final class PendingWrite {
private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() {
private static final ObjectPool<PendingWrite> RECYCLER = ObjectPool.newPool(new ObjectCreator<PendingWrite>() {
@Override
protected PendingWrite newObject(Handle<PendingWrite> handle) {
public PendingWrite newObject(ObjectPool.Handle<PendingWrite> handle) {
return new PendingWrite(handle);
}
};
});
private final Recycler.Handle<PendingWrite> handle;
private final ObjectPool.Handle<PendingWrite> handle;
private PendingWrite next;
private long size;
private ChannelPromise promise;
private Object msg;
private PendingWrite(Recycler.Handle<PendingWrite> handle) {
private PendingWrite(ObjectPool.Handle<PendingWrite> handle) {
this.handle = handle;
}