Skip to content

Commit

Permalink
Fix bug in InternalThreadLocal and provides unit test (#1803)
Browse files Browse the repository at this point in the history
* SerializerFactory 获取Serializer时,锁住整个hashmap,导致整个过程被block

* 单元测试。保证一个class只有一个serializer和deserializer。单线程和多线程测试

* 增加线程数 50 模拟多个线程来获取serializer和deserializer

* 当cores线程数全都使用的情况下,默认线程池会把任务放入到队列中。队列满则再创建线程(总数不会超过Max线程数)
增强线程池:在请求量阶段性出现高峰时使用
特性:cores线程全部使用的情况下,优先创建线程(总数不会超过max),当max个线程全都在忙的情况下,才将任务放入队列。请求量下降时,线程池会自动维持cores个线程,多余的线程退出。

* 当cores线程数全都使用的情况下,默认线程池会把任务放入到队列中。队列满则再创建线程(总数不会超过Max线程数)
增强线程池:在请求量阶段性出现高峰时使用
特性:cores线程全部使用的情况下,优先创建线程(总数不会超过max),当max个线程全都在忙的情况下,才将任务放入队列。请求量下降时,线程池会自动维持cores个线程,多余的线程退出。

* 补全单元测试,测试扩展是否生效

* 错误命名

* 增加@OverRide注解
long 初始化赋值时,小写l改为大写L防止误读

* 修复单元测试

* remove enhanced

* remove enhanced

* Faster ThreadLocal impl in internal use
* Used in RpcContext`s LOCAL field.
* Faster get than the traditional ThreadLocal

* add License

* fix ci failed

* fix ci failed

* fix ci failed

* fix ci failed

* fix ci failed

* remove author info

* fix destroy method

* fix bug at method size.

* Unit test for InternalThreadLocal

* Unit test for InternalThreadLocal
Fix bug in method removeAll
  • Loading branch information
carryxyh authored and beiwei30 committed May 15, 2018
1 parent 71366d6 commit 3c6201c
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ public static void removeAll() {
Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex);
if (v != null && v != InternalThreadLocalMap.UNSET) {
Set<InternalThreadLocal<?>> variablesToRemove = (Set<InternalThreadLocal<?>>) v;
for (InternalThreadLocal<?> tlv : variablesToRemove) {
InternalThreadLocal<?>[] variablesToRemoveArray =
variablesToRemove.toArray(new InternalThreadLocal[variablesToRemove.size()]);
for (InternalThreadLocal<?> tlv : variablesToRemoveArray) {
tlv.remove(threadLocalMap);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,32 @@ public void run() {
Thread.sleep(2000);
}

@Test
public void testRemoveAll() throws InterruptedException {
final InternalThreadLocal<Integer> internalThreadLocal = new InternalThreadLocal<Integer>();
internalThreadLocal.set(1);
Assert.assertTrue("set failed", internalThreadLocal.get() == 1);

final InternalThreadLocal<String> internalThreadLocalString = new InternalThreadLocal<String>();
internalThreadLocalString.set("value");
Assert.assertTrue("set failed", "value".equals(internalThreadLocalString.get()));

InternalThreadLocal.removeAll();
Assert.assertTrue("removeAll failed!", internalThreadLocal.get() == null);
Assert.assertTrue("removeAll failed!", internalThreadLocalString.get() == null);
}

@Test
public void testSize() throws InterruptedException {
final InternalThreadLocal<Integer> internalThreadLocal = new InternalThreadLocal<Integer>();
internalThreadLocal.set(1);
Assert.assertTrue("size method is wrong!", InternalThreadLocal.size() == 1);

final InternalThreadLocal<String> internalThreadLocalString = new InternalThreadLocal<String>();
internalThreadLocalString.set("value");
Assert.assertTrue("size method is wrong!", InternalThreadLocal.size() == 2);
}

@Test
public void testSetAndGet() {
final Integer testVal = 10;
Expand All @@ -70,6 +96,33 @@ public void testSetAndGet() {
Objects.equals(testVal, internalThreadLocal.get()));
}

@Test
public void testRemove() {
final InternalThreadLocal<Integer> internalThreadLocal = new InternalThreadLocal<Integer>();
internalThreadLocal.set(1);
Assert.assertTrue("get method false!", internalThreadLocal.get() == 1);

internalThreadLocal.remove();
Assert.assertTrue("remove failed!", internalThreadLocal.get() == null);
}

@Test
public void testOnRemove() {
final Integer[] valueToRemove = {null};
final InternalThreadLocal<Integer> internalThreadLocal = new InternalThreadLocal<Integer>() {
@Override
protected void onRemoval(Integer value) throws Exception {
//value calculate
valueToRemove[0] = value + 1;
}
};
internalThreadLocal.set(1);
Assert.assertTrue("get method false!", internalThreadLocal.get() == 1);

internalThreadLocal.remove();
Assert.assertTrue("onRemove method failed!", valueToRemove[0] == 2);
}

@Test
public void testMultiThreadSetAndGet() throws InterruptedException {
final Integer testVal1 = 10;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 com.alibaba.dubbo.common.threadlocal;

import org.junit.Assert;
import org.junit.Test;

public class NamedInternalThreadFactoryTest {

@Test
public void newThread() throws Exception {
NamedInternalThreadFactory namedInternalThreadFactory = new NamedInternalThreadFactory();
Thread t = namedInternalThreadFactory.newThread(new Runnable() {
@Override
public void run() {

}
});
Assert.assertTrue("thread is not InternalThread", t.getClass().equals(InternalThread.class));
}
}

0 comments on commit 3c6201c

Please sign in to comment.