1 | /******************************************************************************* | |
2 | * Copyhacked (H) 2012-2020. | |
3 | * This program and the accompanying materials | |
4 | * are made available under no term at all, use it like | |
5 | * you want, but share and discuss about it | |
6 | * every time possible with every body. | |
7 | * | |
8 | * Contributors: | |
9 | * ron190 at ymail dot com - initial implementation | |
10 | ******************************************************************************/ | |
11 | package com.jsql.util; | |
12 | ||
13 | import com.jsql.model.InjectionModel; | |
14 | import com.jsql.model.bean.database.AbstractElementDatabase; | |
15 | import com.jsql.model.suspendable.AbstractSuspendable; | |
16 | import com.jsql.model.suspendable.callable.ThreadFactoryCallable; | |
17 | import org.apache.logging.log4j.LogManager; | |
18 | import org.apache.logging.log4j.Logger; | |
19 | ||
20 | import java.util.HashMap; | |
21 | import java.util.Map; | |
22 | import java.util.concurrent.ConcurrentHashMap; | |
23 | import java.util.concurrent.ExecutorService; | |
24 | import java.util.concurrent.Executors; | |
25 | import java.util.concurrent.TimeUnit; | |
26 | ||
27 | /** | |
28 | * Utility class managing running threads on which the user can act. | |
29 | * It must be noted that as SwingWorker class are used then only 10 jobs can be run | |
30 | * at the same time, the 11th will be waiting in the thread pool until one of the 10 | |
31 | * actives one is freed. | |
32 | */ | |
33 | public final class ThreadUtil { | |
34 | | |
35 | /** | |
36 | * Log4j logger sent to view. | |
37 | */ | |
38 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
39 | | |
40 | /** | |
41 | * List of running jobs associated to a database injection task. | |
42 | * We can interact with those tasks in order to pause/resume and stop the process. | |
43 | */ | |
44 | // Fix #8258: ConcurrentModificationException on java.util.HashMap$ValueIterator.next() | |
45 | private final Map<AbstractElementDatabase, AbstractSuspendable> suspendables = new ConcurrentHashMap<>(new HashMap<>()); | |
46 | ||
47 | private final InjectionModel injectionModel; | |
48 | | |
49 | public ThreadUtil(InjectionModel injectionModel) { | |
50 | this.injectionModel = injectionModel; | |
51 | } | |
52 | ||
53 | /** | |
54 | * Add a job to the list of ongoing tasks. It is used to allow the user to act | |
55 | * on the job and stop/pause a running process. | |
56 | * @param elementDatabase component associated to the active job | |
57 | * @param suspendable active job to act on | |
58 | */ | |
59 | public void put(AbstractElementDatabase elementDatabase, AbstractSuspendable suspendable) { | |
60 | this.suspendables.put(elementDatabase, suspendable); | |
61 | } | |
62 | | |
63 | /** | |
64 | * Get the task associated to the database component. | |
65 | * It's usually done to act on the task like stop/pause the corresponding process, or | |
66 | * to check the status of the job. | |
67 | * @param elementDatabase component associated to the active job | |
68 | * @return job currently running | |
69 | */ | |
70 | public AbstractSuspendable get(AbstractElementDatabase elementDatabase) { | |
71 |
1
1. get : replaced return value with null for com/jsql/util/ThreadUtil::get → NO_COVERAGE |
return this.suspendables.get(elementDatabase); |
72 | } | |
73 | | |
74 | /** | |
75 | * Remove the thread corresponding to the component in order to be | |
76 | * garbage collected. The thread should be stopped prior the deletion. | |
77 | * @param elementDatabase component associated to thread | |
78 | */ | |
79 | public void remove(AbstractElementDatabase elementDatabase) { | |
80 | this.suspendables.remove(elementDatabase); | |
81 | } | |
82 | | |
83 | /** | |
84 | * Force to stop every threads still running and empty the list where | |
85 | * they were instantiated in order to be garbage collected. | |
86 | */ | |
87 | public void reset() { | |
88 | | |
89 |
1
1. reset : removed call to java/util/Collection::forEach → NO_COVERAGE |
this.suspendables.values().forEach(AbstractSuspendable::stop); |
90 |
1
1. reset : removed call to java/util/Map::clear → NO_COVERAGE |
this.suspendables.clear(); |
91 | } | |
92 | | |
93 | public ExecutorService getExecutor(String nameThread) { | |
94 | ||
95 | ExecutorService taskExecutor; | |
96 | | |
97 |
1
1. getExecutor : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingThreads()) { |
98 | | |
99 | int countThreads = this.injectionModel.getMediatorUtils().getPreferencesUtil().countLimitingThreads(); | |
100 | taskExecutor = Executors.newFixedThreadPool(countThreads, new ThreadFactoryCallable(nameThread)); | |
101 | | |
102 | } else { | |
103 | taskExecutor = Executors.newCachedThreadPool(new ThreadFactoryCallable(nameThread)); | |
104 | } | |
105 | | |
106 |
1
1. getExecutor : replaced return value with null for com/jsql/util/ThreadUtil::getExecutor → NO_COVERAGE |
return taskExecutor; |
107 | } | |
108 | ||
109 | public void shutdown(ExecutorService taskExecutor) { | |
110 | ||
111 | int timeout = 15; | |
112 |
1
1. shutdown : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isConnectionTimeout()) { |
113 | timeout = this.injectionModel.getMediatorUtils().getPreferencesUtil().countConnectionTimeout(); | |
114 | } | |
115 | ||
116 | try { | |
117 |
1
1. shutdown : removed call to java/util/concurrent/ExecutorService::shutdown → NO_COVERAGE |
taskExecutor.shutdown(); |
118 |
1
1. shutdown : negated conditional → NO_COVERAGE |
if (!taskExecutor.awaitTermination(timeout, TimeUnit.SECONDS)) { |
119 | taskExecutor.shutdownNow(); | |
120 | } | |
121 | } catch (InterruptedException e) { | |
122 | ||
123 | LOGGER.log(LogLevelUtil.IGNORE, e, e); | |
124 |
1
1. shutdown : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
125 | } | |
126 | } | |
127 | } | |
Mutations | ||
71 |
1.1 |
|
89 |
1.1 |
|
90 |
1.1 |
|
97 |
1.1 |
|
106 |
1.1 |
|
112 |
1.1 |
|
117 |
1.1 |
|
118 |
1.1 |
|
124 |
1.1 |