1 package fileIO;
2 
3 import java.util.Arrays;
4 
5 import shared.Shared;
6 import shared.Tools;
7 
8 /**
9  * @author Brian Bushnell
10  * @date Jan 2, 2013
11  *
12  */
13 public class LoadThread<X> extends Thread{
14 
load(String fname, Class<Y> c)15 	public static <Y> LoadThread<Y> load(String fname, Class<Y> c){
16 		LoadThread<Y> lt=new LoadThread<Y>(fname, c);
17 		lt.start();
18 		return lt;
19 	}
20 
LoadThread(String fname_, Class<X> c_)21 	private LoadThread(String fname_, Class<X> c_){
22 		fname=fname_;
23 		c=c_;
24 		addThread(1);
25 	}
26 
27 	@Override
run()28 	public void run(){
29 		addRunningThread(1);
30 		output=ReadWrite.read(c, fname, false);
31 		addRunningThread(-1);
32 		synchronized(this){this.notify();}
33 	}
34 
35 
addThread(int x)36 	private static final int addThread(int x){
37 		final int lim=(Shared.LOW_MEMORY ? 1 : LIMIT);
38 		synchronized(activeThreads){
39 			assert(x!=0);
40 			if(x>0){
41 				activeThreads[0]+=x;
42 				activeThreads[1]+=x;
43 			}else{
44 				addRunningThread(x);
45 			}
46 			assert(activeThreads[0]==(activeThreads[1]+activeThreads[2]) && activeThreads[0]>=0 && activeThreads[1]>=0 &&
47 					activeThreads[2]>=0 && activeThreads[2]<=lim) : Arrays.toString(activeThreads);
48 
49 			return activeThreads[0];
50 		}
51 	}
52 
addRunningThread(int x)53 	private static final int addRunningThread(int x){
54 		final int lim=(Shared.LOW_MEMORY ? 1 : LIMIT);
55 		synchronized(activeThreads){
56 			assert(x!=0);
57 			if(x>0){
58 				assert(activeThreads[1]>=x);
59 				while(activeThreads[2]>=lim){
60 					try {
61 						activeThreads.wait();
62 					} catch (InterruptedException e) {
63 						// TODO Auto-generated catch block
64 						e.printStackTrace();
65 					}
66 				}
67 				activeThreads[1]-=x; //Remove from waiting
68 			}else{
69 				activeThreads[0]+=x; //Remove from active
70 			}
71 			activeThreads[2]+=x; //Change number running
72 
73 			assert(activeThreads[0]==(activeThreads[1]+activeThreads[2]) && activeThreads[0]>=0 && activeThreads[1]>=0 &&
74 					activeThreads[2]>=0 && activeThreads[2]<=lim) : Arrays.toString(activeThreads);
75 
76 			if(activeThreads[2]==0 || (activeThreads[2]<lim && activeThreads[1]>0)){activeThreads.notify();}
77 //			System.err.println(activeThreads[2]);
78 //			try {
79 //				activeThreads.wait(5000);
80 //			} catch (InterruptedException e) {
81 //				// TODO Auto-generated catch block
82 //				e.printStackTrace();
83 //			}
84 			return activeThreads[2];
85 		}
86 	}
87 
countActiveThreads()88 	public static final int countActiveThreads(){
89 		final int lim=(Shared.LOW_MEMORY ? 1 : LIMIT);
90 		synchronized(activeThreads){
91 			assert(activeThreads[0]==(activeThreads[1]+activeThreads[2]) && activeThreads[0]>=0 && activeThreads[1]>=0 &&
92 					activeThreads[2]>=0 && activeThreads[2]<=lim) : Arrays.toString(activeThreads);
93 			return activeThreads[0];
94 		}
95 	}
96 
waitForReadingToFinish()97 	public static final void waitForReadingToFinish(){
98 		final int lim=(Shared.LOW_MEMORY ? 1 : LIMIT);
99 		synchronized(activeThreads){
100 			while(activeThreads[0]>0){
101 				assert(activeThreads[0]==(activeThreads[1]+activeThreads[2]) && activeThreads[0]>=0 && activeThreads[1]>=0 &&
102 						activeThreads[2]>=0 && activeThreads[2]<=lim) : Arrays.toString(activeThreads);
103 				try {
104 					activeThreads.wait(8000);
105 				} catch (InterruptedException e) {
106 					// TODO Auto-generated catch block
107 					e.printStackTrace();
108 				}
109 				if(activeThreads[2]==0 || (activeThreads[2]<lim && activeThreads[1]>0)){activeThreads.notify();}
110 			}
111 		}
112 	}
113 
waitForThisToFinish()114 	public final void waitForThisToFinish(){
115 		if(output==null){
116 			while(this.getState()!=State.TERMINATED){
117 				try {
118 					this.join();
119 				} catch (InterruptedException e) {
120 					// TODO Auto-generated catch block
121 					e.printStackTrace();
122 				}
123 			}
124 		}
125 	}
126 
127 	/** {active, waiting, running} <br>
128 	 * Active means running or waiting.
129 	 */
130 	public static int[] activeThreads={0, 0, 0};
131 
132 	private final String fname;
133 	private final Class<X> c;
134 	public X output=null;
135 
136 	private static final int[] RUNNING=new int[1];
137 	public static int LIMIT=Tools.min(12, Tools.max(Shared.threads(), 1));
138 
139 }
140