1
1
package com .fasterxml .jackson .databind .util ;
2
2
3
+ import java .lang .invoke .MethodHandle ;
4
+ import java .lang .invoke .MethodHandles ;
5
+ import java .lang .invoke .MethodType ;
3
6
import java .nio .charset .StandardCharsets ;
7
+ import java .util .function .Predicate ;
4
8
5
9
import com .fasterxml .jackson .annotation .JsonPropertyOrder ;
6
10
@@ -54,6 +58,10 @@ public void testParserWithBoundedPool() throws Exception {
54
58
_testParser (JsonRecyclerPools .sharedBoundedPool ());
55
59
}
56
60
61
+ public void testParserWithHybridPool () throws Exception {
62
+ _testParser (new HybridTestPool ());
63
+ }
64
+
57
65
private void _testParser (RecyclerPool <BufferRecycler > pool ) throws Exception
58
66
{
59
67
ObjectMapper mapper = JsonMapper .builder (
@@ -100,6 +108,10 @@ public void testGeneratorWithBoundedPool() throws Exception {
100
108
_testGenerator (JsonRecyclerPools .sharedBoundedPool ());
101
109
}
102
110
111
+ public void testGeneratorWithHybridPool () throws Exception {
112
+ _testGenerator (new HybridTestPool ());
113
+ }
114
+
103
115
private void _testGenerator (RecyclerPool <BufferRecycler > pool ) throws Exception
104
116
{
105
117
ObjectMapper mapper = JsonMapper .builder (
@@ -115,4 +127,65 @@ private void _testGenerator(RecyclerPool<BufferRecycler> pool) throws Exception
115
127
assertEquals (EXP , new String (mapper .writeValueAsBytes (new Pojo4321 (-42 , "bogus" )),
116
128
StandardCharsets .UTF_8 ));
117
129
}
130
+
131
+ static class HybridTestPool implements RecyclerPool <BufferRecycler >
132
+ {
133
+ private static final long serialVersionUID = 1L ;
134
+
135
+ private static final Predicate <Thread > isVirtual = VirtualPredicate .findIsVirtualPredicate ();
136
+
137
+ private final RecyclerPool <BufferRecycler > nativePool = JsonRecyclerPools .threadLocalPool ();
138
+ private final RecyclerPool <BufferRecycler > virtualPool = JsonRecyclerPools .newLockFreePool ();
139
+
140
+ @ Override
141
+ public BufferRecycler acquirePooled () {
142
+ return isVirtual .test (Thread .currentThread ()) ?
143
+ virtualPool .acquirePooled () :
144
+ nativePool .acquirePooled ();
145
+ }
146
+
147
+ @ Override
148
+ public void releasePooled (BufferRecycler pooled ) {
149
+ if (isVirtual .test (Thread .currentThread ())) {
150
+ virtualPool .releasePooled (pooled );
151
+ } else {
152
+ nativePool .releasePooled (pooled );
153
+ }
154
+ }
155
+
156
+ static class VirtualPredicate {
157
+ static final MethodHandle virtualMh = findVirtualMH ();
158
+
159
+ static MethodHandle findVirtualMH () {
160
+ try {
161
+ return MethodHandles .publicLookup ().findVirtual (Thread .class , "isVirtual" ,
162
+ MethodType .methodType (boolean .class ));
163
+ } catch (Exception e ) {
164
+ return null ;
165
+ }
166
+ }
167
+
168
+ static Predicate <Thread > findIsVirtualPredicate () {
169
+ if (virtualMh != null ) {
170
+ return new Predicate <Thread >() {
171
+ @ Override
172
+ public boolean test (Thread thread ) {
173
+ try {
174
+ return (boolean ) virtualMh .invokeExact (thread );
175
+ } catch (Throwable e ) {
176
+ throw new RuntimeException (e );
177
+ }
178
+ }
179
+ };
180
+ }
181
+
182
+ return new Predicate <Thread >() {
183
+ @ Override
184
+ public boolean test (Thread thread ) {
185
+ return false ;
186
+ }
187
+ };
188
+ }
189
+ }
190
+ }
118
191
}
0 commit comments