blob: 5e692d6cf25edfcf5b9d14f5111a665d43897f53 [file] [log] [blame]
Thomas Vachuska9c17a6d2015-02-17 23:36:43 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska9c17a6d2015-02-17 23:36:43 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onlab.util;
17
18import org.apache.commons.lang3.concurrent.ConcurrentUtils;
19
20import java.util.concurrent.ConcurrentHashMap;
21import java.util.concurrent.ThreadFactory;
22
23import static com.google.common.base.MoreObjects.toStringHelper;
24
25/**
26 * Thread factory for creating threads that belong to the specified thread group.
27 */
28public final class GroupedThreadFactory implements ThreadFactory {
29
30 public static final String DELIMITER = "/";
31
32 private final ThreadGroup group;
33
34 // Cache of created thread factories.
35 private static final ConcurrentHashMap<String, GroupedThreadFactory> FACTORIES =
36 new ConcurrentHashMap<>();
37
38 /**
39 * Returns thread factory for producing threads associated with the specified
40 * group name. The group name-space is hierarchical, based on slash-delimited
41 * name segments, e.g. {@code onos/intent}.
42 *
43 * @param groupName group name
44 * @return thread factory
45 */
46 public static GroupedThreadFactory groupedThreadFactory(String groupName) {
47 GroupedThreadFactory factory = FACTORIES.get(groupName);
48 if (factory != null) {
49 return factory;
50 }
51
52 // Find the parent group or root the group hierarchy under default group.
53 int i = groupName.lastIndexOf(DELIMITER);
54 if (i > 0) {
55 String name = groupName.substring(0, i);
56 ThreadGroup parentGroup = groupedThreadFactory(name).threadGroup();
57 factory = new GroupedThreadFactory(new ThreadGroup(parentGroup, groupName));
58 } else {
59 factory = new GroupedThreadFactory(new ThreadGroup(groupName));
60 }
61
62 return ConcurrentUtils.putIfAbsent(FACTORIES, groupName, factory);
63 }
64
65 // Creates a new thread group
66 private GroupedThreadFactory(ThreadGroup group) {
67 this.group = group;
68 }
69
70 /**
71 * Returns the thread group associated with the factory.
72 *
73 * @return thread group
74 */
75 public ThreadGroup threadGroup() {
76 return group;
77 }
78
79 @Override
80 public Thread newThread(Runnable r) {
81 return new Thread(group, r);
82 }
83
84 @Override
85 public String toString() {
86 return toStringHelper(this).add("group", group).toString();
87 }
88}