Statistics
| Revision:

gvsig-raster / org.gvsig.raster.cache / trunk / org.gvsig.raster.cache / org.gvsig.raster.cache.lib.impl / src / main / java / org / gvsig / raster / cache / tile / impl / pool / ThreadPoolImpl.java @ 990

History | View | Annotate | Download (4.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.cache.tile.impl.pool;
23

    
24
import java.util.Collections;
25
import java.util.LinkedList;
26

    
27
import org.gvsig.raster.cache.tile.Tile;
28
import org.gvsig.raster.cache.tile.exception.TileGettingException;
29
import org.gvsig.raster.cache.tile.pool.AtomicTask;
30
import org.gvsig.raster.cache.tile.pool.ThreadPool;
31
import org.gvsig.raster.cache.tile.pool.TilePipe;
32
import org.gvsig.raster.cache.tile.provider.TileListener;
33

    
34
/**
35
 * Pool of threads. This class contains a list of tasks and a limited number
36
 * of threads to execute them. When a thread is free will execute the next task 
37
 * in the list. 
38
 *
39
 * @author Nacho Brodin (nachobrodin@gmail.com)
40
 */
41
public class ThreadPoolImpl implements ThreadPool {
42
        private int                        NTHREADS_POOL   = 5;
43
        private ThreadTask[]               threadList      = null;
44
        private LinkedList<AtomicTask>     tasks           = new LinkedList<AtomicTask>();
45
        private boolean                    priorityActive  = false;
46
        private TilePipe                   tilePipe        = null;
47

    
48
        /**
49
         * Constructor. Only for testing purposes. After this constructor the method init
50
         * has to be called
51
         */
52
        public ThreadPoolImpl() {
53
                this.priorityActive = true;
54
                threadList = new ThreadTask[NTHREADS_POOL];
55
        }
56
        
57
        /**
58
         * Constructor
59
         * @param priorityActive true if the pool runs using priorities and false if doesn't
60
         * @param nThreads Number of threads of this pool
61
         */
62
        public ThreadPoolImpl(boolean priorityActive, int nThreads) {
63
                this.priorityActive = true;
64
                NTHREADS_POOL = nThreads;
65
                init();
66
        }
67
        
68
        /**
69
         * Constructor
70
         * @param priorityActive true if the pool runs using priorities and false if doesn't
71
         */
72
        public ThreadPoolImpl(boolean priorityActive) {
73
                this.priorityActive = priorityActive;
74
                init();
75
        }
76
        
77
        public void init() {
78
                if(threadList == null)
79
                        threadList = new ThreadTask[NTHREADS_POOL];
80
                for (int i = 0; i < NTHREADS_POOL; i++) {
81
                        threadList[i] = new ThreadTask(this);
82
                        threadList[i].start();
83
                }
84
        }
85
        
86
        /**
87
         * Cancel the pool of threads
88
         * @param listener
89
         */
90
        public void cancelPool(TileListener listener) {
91
                if(threadList != null) {
92
                        for (int i = 0; i < NTHREADS_POOL; i++) {
93
                                if(threadList[i] != null) {
94
                                        Runnable r = threadList[i].stopThread();
95
                                        try {
96
                                                listener.tileReady((Tile)r);
97
                                        } catch (TileGettingException e) {
98
                                        }
99
                                }
100
                        }
101
                }
102
                for (int i = 0; i < tasks.size(); i++) {
103
                        try {
104
                                listener.tileReady((Tile)tasks.get(i));
105
                        } catch (TileGettingException e) {
106
                        }
107
                }
108
                synchronized (tasks) {
109
                        tasks.notifyAll();
110
                }
111
                destroyPool();
112
        }
113
        
114
        /*
115
         * (non-Javadoc)
116
         * @see org.gvsig.raster.cache.tile.pool.ThreadPool#getTilePipe()
117
         */
118
        public TilePipe getTilePipe() {
119
                if(tilePipe == null)
120
                        tilePipe = new TilePipeImpl();
121
                return tilePipe;
122
        }
123
        
124
        /**
125
         * Stops all threads in the list and sets the list to null
126
         */
127
        public void destroyPool() {
128
                for (int i = 0; i < NTHREADS_POOL; i++) {
129
                        threadList[i].stopThread();
130
                        threadList[i] = null;
131
                }
132
                threadList = null;
133
        }
134
        
135
        /**
136
         * Returns true if the pool is valid
137
         * @return
138
         */
139
        public boolean isPoolValid() {
140
                return !(threadList == null);
141
        }
142

    
143
        /**
144
         * Adds a new task to the list
145
         * @param task
146
         */
147
        public void addTask(AtomicTask task) {
148
                synchronized (tasks) {
149
                        tasks.addLast(task);
150
                        tasks.notify();
151
                }
152
        }
153

    
154
        /**
155
         * Gets the next task in the list
156
         * @return
157
         */
158
        public Runnable getNext() {
159
                Runnable returnVal = null;
160
                synchronized (tasks) {
161
                        while (tasks.isEmpty()) {
162
                                try {
163
                                        tasks.wait();
164
                                } catch (InterruptedException ex) {
165
                                        System.err.println("Interrupted");
166
                                }
167
                        }
168
                        if(priorityActive)
169
                                sort(tasks);
170
                        returnVal = (Runnable) tasks.removeFirst();
171
                }
172
                return returnVal;
173
        }
174
        
175
        /**
176
         * Sorts the array of tasks. Each atomic task have to implement AtomicTask interface
177
         * which is Runnable and Comparable. The last one allow to sort the array 
178
         * by priorities.
179
         * @param tasks
180
         */
181
        private void sort(LinkedList<AtomicTask> tasks) {
182
                Collections.sort(tasks);
183
        }
184
}