doGoalTriggering(List)
last analyzed

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 1
c 0
b 0
f 0
1
package it.cnr.istc.pst.cognition.koala.reasoner.goal;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import it.cnr.istc.pst.cognition.koala.reasoner.observation.ObservationReasoner;
7
import it.cnr.istc.pst.cognition.koala.reasoner.observation.ObservationReasonerUpdate;
8
9
/**
10
 * 
11
 * @author anacleto
12
 *
13
 */
14
public abstract class GoalReasoner implements ObservationListener
15
{
16
	protected ObservationReasoner environment;					// environment model at observation level
17
	
18
	private final List<ObservationReasonerUpdate> updates;		// list of cached notifications from observation reasoner
19
	protected Thread process;									// goal triggering background process
20
	
21
	/**
22
	 * 
23
	 */
24
	public GoalReasoner() {
25
		// set updates 
26
		this.updates = new ArrayList<ObservationReasonerUpdate>();
27
	}
28
29
	/**
30
	 * 
31
	 * @param env
32
	 * @throws Exception
33
	 */
34
	public void init(ObservationReasoner env) 
35
			throws Exception 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
36
	{
37
		// set environment
38
		this.environment = env;
39
		this.environment.subscribe(this);
40
		
41
		// set wait flag
42
		synchronized (this.updates) {
43
			this.updates.clear();
44
			this.updates.notifyAll();
45
		}
46
		
47
		// check already running process
48
		if (this.process != null && this.process.isAlive()) {
49
			// stop process
50
			this.process.interrupt();
51
			this.process.wait();
0 ignored issues
show
Bug Multi Threading introduced by
Move this call to "wait()" into a synchronized block to be sure the monitor on "Thread" is held.
Loading history...
Bug Multi Threading introduced by
It is good practice to wrap calls to wait in a while loop. Very rarely, a thread may be woken, even though the lock condition is not fulfilled (spurious wakeups). Using a while loop will guard against these wakeups.

The Java documentation on Condition discusses spurious wakeups.

Loading history...
Bug Multi Threading introduced by
Thread instances should never be used as a monitor. The JVM relies on the Thread.wait(), Thread.notify() and Thread.notifyAll methods to change the state of a thread. Please refactor your code to use another kind of object as your monitor.

For a good explanation of how monitor locks work, you may refer to Chapter 20 Thread Synchronization of Inside the Java Virtual Machine by Bill Venners which is available online.

Loading history...
52
		}
53
		
54
		// create background thread
55
		this.process = new Thread(new Runnable() {
56
			
57
			/**
58
			 * 
59
			 */
60
			public void run() 
61
			{
62
				boolean run = true;
63
				while (run)
64
				{
65
					try
66
					{
67
						// list of updates to handle
68
						List<ObservationReasonerUpdate> list = new ArrayList<ObservationReasonerUpdate>();
69
						// wait a signal
70
						synchronized (updates) {
71
							// check signal flag
72
							while (updates.isEmpty()) {
73
								// wait signal
74
								updates.wait();
75
							}
76
77
							// get updates
78
							list.addAll(updates);
79
							// clear 
80
							updates.clear();
81
							// release lock
82
							updates.notifyAll();
83
						}
84
85
						
86
						// do goal triggering if necessary
87
						doGoalTriggering(list);
88
					}
89
					catch (InterruptedException ex) {
0 ignored issues
show
introduced by
Either re-interrupt this method or rethrow the "InterruptedException".
Loading history...
90
						// stop goal triggering
91
						run = false;
92
					}
93
				}
94
			}
95
		});
96
		
97
		// complete initialization
98
		this.doInitialize(this.environment);
99
		
100
		
101
		// check if initialize
102
		if (this.process != null && !this.process.isAlive()) {
103
			// start background process
104
			this.process.start();
105
		}
106
	}
107
	
108
	/**
109
	 * 
110
	 * @throws Exception
111
	 */
112
	public void close() 
113
			throws Exception 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
114
	{
115
		// check if process is running
116
		if (this.process != null && this.process.isAlive()) {
117
			// interrupt process
118
			this.process.interrupt();
119
			this.process.join();
120
		}
121
		
122
		// complete process interruption
123
		this.doClose();
124
	}
125
	
126
	/**
127
	 * 
128
	 */
129
	public void update(List<ObservationReasonerUpdate> notifications) 
130
	{
131
		// notify internal goal triggering process
132
		synchronized (this.updates) {
133
			// add all updates
134
			this.updates.addAll(notifications);
135
			// release lock
136
			this.updates.notifyAll();
137
		}
138
	}
139
	
140
	/**
141
	 * 
142
	 */
143
	protected abstract void doInitialize(ObservationReasoner env);
144
	
145
	/**
146
	 * 
147
	 */
148
	protected abstract void doGoalTriggering(List<ObservationReasonerUpdate> notifications);
149
	
150
	/**
151
	 * 
152
	 */
153
	protected abstract void doClose();
154
}
155