Guest User

Untitled

a guest
Oct 21st, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.50 KB | None | 0 0
  1.  
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. import java.io.BufferedReader;
  5. import java.io.InputStreamReader;
  6. import java.util.Random;
  7.  
  8. import java.lang.String;
  9.  
  10.  
  11.  
  12. class Operation // операция по заполнению
  13. {
  14. int startPosition; // с какой ячейки начали заполнять память
  15. int size; //сколько памяти заполнили
  16. int data; //чем заполнили
  17. int ThreadNum; //какой поток это хотел
  18. int num; //какой номер (айди) у этого запроса ( он может совпадать у разных потоков)
  19. Operation(int stPos, int length, int data, int ThreadNum, int num)
  20. {
  21. startPosition = stPos;
  22. this.size = length;
  23. this.data = data;
  24. this.ThreadNum = ThreadNum;
  25. this.num = num;
  26.  
  27. }
  28. // функции - getter`ы
  29. final int size()
  30. {
  31. return size;
  32. }
  33. final int ThreadNum()
  34. {
  35. return ThreadNum;
  36. }
  37. final int data()
  38. {
  39. return data;
  40. }
  41. final int num()
  42. {
  43. return num;
  44. }
  45. final int startPosition()
  46. {
  47. return startPosition;
  48. }
  49.  
  50. }
  51.  
  52.  
  53. class Request // запрос
  54. {
  55. int size;
  56. int ThreadNum;// вместе номер потока и номер запроса однозначно определяют запрос
  57. int data;
  58. int num;//номер запроса
  59. Request(int size, int ThreadNum, int data,int num)
  60. {
  61. this.size = size;;
  62. this.ThreadNum = ThreadNum;
  63. this.data = data;
  64. this.num = num;
  65. }
  66. final int size()
  67. {
  68. return size;
  69. }
  70. final int ThreadNum()
  71. {
  72. return ThreadNum;
  73. }
  74. final int data()
  75. {
  76. return data;
  77. }
  78. final int num()
  79. {
  80. return num;
  81. }
  82. }
  83. class file // снгл-класс для доступа к файлу остальными классами
  84. {
  85. public static FileWriter getInstance()
  86. {
  87. if(instance == null)
  88. instance = new file();
  89. return os;
  90. }
  91. private static FileWriter os;
  92. private static file instance;
  93. file()
  94. {
  95. try {
  96. os = new FileWriter("data.txt");
  97. } catch (IOException e) {
  98. // TODO Auto-generated catch block
  99. e.printStackTrace();
  100. }
  101. }
  102. }
  103.  
  104. class Data
  105. {
  106.  
  107. private int arr[]; //массив с данными (память)
  108. private Stack <Request> stackOfRequests; //массив запросов
  109. private Stack <Operation> stackOfOperations; //массив операций
  110. private static Data instance = new Data();
  111. boolean isReady = true;
  112. public static Data getInstance(){ //синглтон
  113. if(instance == null)
  114. instance = new Data();
  115. return instance;
  116. }
  117. private Data(){
  118. stackOfRequests = new Stack<Request>();
  119. stackOfOperations = new Stack <Operation>();
  120. arr = new int[5000];
  121.  
  122. }
  123. private int FindPlace(int size){ // получает длинну памяти которая нужна и ищет такой кусок который заполнен нулями
  124. int j;
  125. for(int i = 0; i < 5000; i++)
  126. {
  127. for( j = i; j < 5000; j++)
  128. {
  129. if(arr[j] != 0 || j-i > size)
  130. break;
  131. }
  132. if(j-i > size)
  133. return i;
  134. }
  135. return 0;
  136. }
  137. public final boolean isReady(){return isReady;}
  138.  
  139. private void Fill(){ // заполняет массив памяти извлекая запросы из стека
  140. Request req = stackOfRequests.pop(); // извлекает запрос из стека
  141. int place = FindPlace(req.size()); // ищет индекс места в массиве
  142. Operation op = new Operation( place, // указаетль на начало памяти которая будет заполнена
  143. req.size(), //размер памяти котоый будет заполнен
  144. req.data(), // цифры которыми заполнится память
  145. req.ThreadNum(),// номер потока чей это был запрос
  146. req.num()); // номер запроса у этого потока ( для дальнейшей идентификации операции чтобы ее можно было отменить)
  147.  
  148.  
  149. //создается новая операция (отличается от запроса тем что запрос - это пожелание потока на заполнение данными а операция - это конкретно выполненная операция
  150.  
  151.  
  152. stackOfOperations.push(op); //добавляем эту оперцаию (чтобы ее можно было отменить найдя среди других по номеру потока и номеру запроса)
  153. for(int i = place; i < place+req.size();i++)
  154. arr[i] = req.data(); //заполняем кусок от ячейки place размером size
  155. try {
  156. file.getInstance().write(req.ThreadNum()+ "," + req.size()); //записываем в файл эту оперцию в виде "номер_потока,длина_запроса"
  157. file.getInstance().write(System.getProperty("line.separator"));
  158. } catch (IOException e1) {
  159. // TODO Auto-generated catch block
  160. e1.printStackTrace();
  161. }
  162.  
  163. }
  164. private void Out()
  165. {
  166.  
  167. for(int i = 0; i < 50; i++)
  168. {
  169.  
  170. try {
  171. file.getInstance().write(arr[i]+ " ");
  172. } catch (IOException e) {
  173. // TODO Auto-generated catch block
  174. e.printStackTrace();
  175. }
  176.  
  177. }
  178.  
  179. try {
  180. file.getInstance().write(System.getProperty("line.separator"));// фигня для записи новой строки
  181. } catch (IOException e) {
  182. // TODO Auto-generated catch block
  183. e.printStackTrace();
  184. }
  185.  
  186.  
  187. }
  188. synchronized public void GetRequest(Request req){ // получает запрос за заполнение памяти
  189. isReady = false;
  190. try {
  191. wait(); // говорит что занят
  192. } catch (InterruptedException e) {
  193. // TODO Auto-generated catch block
  194. e.printStackTrace();
  195. }
  196. if(stackOfRequests.push(req) == -1) // если не удалось добавить запрос в стек
  197. {
  198. isReady = true;
  199. return;
  200. }
  201. Fill();// если удалось вызывает этот метод
  202. Out(); // выводим массив в файл
  203. isReady = true;
  204. notify(); // сообщает об освобождении
  205. }
  206. synchronized public void GetCancel(int ThreadNum, int operationNum){ // фактически смысле в переменной isReady нету - это чисто показуха потому что функция синхронайзед и присутсивуют методы wait() и notify() который говорят потокам другим что в данный момент метод занят а нотифай сообщает что он освободился
  207. isReady = false;
  208. try {
  209. wait();
  210. } catch (InterruptedException e1) {
  211. // TODO Auto-generated catch block
  212. e1.printStackTrace();
  213. }
  214. Operation op = stackOfOperations.Find(ThreadNum, operationNum);
  215. if(op == null){
  216. isReady = true;
  217. return;
  218. }
  219.  
  220. stackOfOperations.KickLastFind();
  221. for(int i = op.startPosition(); i < op.startPosition()+op.size; i++)
  222. arr[i] = 0;
  223. try {
  224. file.getInstance().write("Отменяем операцию "+ op.ThreadNum()+","+ op.size());
  225. file.getInstance().write(System.getProperty("line.separator"));
  226. } catch (IOException e) {
  227. // TODO Auto-generated catch block
  228. e.printStackTrace();
  229. }
  230. Out();
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238. isReady = true;
  239. notify();
  240. }
  241. }
  242. class MyThread extends Thread
  243. {
  244.  
  245. Request arrOfRequests[]; //массив запросов. каждый
  246. int numOfRequests = 0; //количество запросов
  247. int toSend = 0; //индекс последнего отправленного запроса ( т.к. новый запрос может создаться, но не отправиться из-за занятости памяти, в таком случае сохранится индекс его и он отправиться as soon as
  248. MyThread(String threadName)
  249. {
  250. super(threadName);
  251. arrOfRequests = new Request[500];
  252.  
  253. start(); //в конструкторе запускаем поток (он запускается при вызове метода старт который вызывает внутри себя метод ран
  254. }
  255. public void run()
  256. {
  257. //System.out.println("Добавлен поток с номером " + this.getName());
  258. while(true)
  259. {
  260. Random r = new Random(); // обьект для генерирования произв чисел
  261. int k = r.nextInt()%2; // генерируем или один или ноль
  262. int name = Integer.parseInt(this.getName());
  263. if(k == 0 || numOfRequests == 0) // если ноль ( или если запросов еще не было т.к. нету смысла в удалении запроса если его не было) то добавляем новый запрос
  264. {
  265. int length = Math.abs(r.nextInt()%10); // генерируем длину для заполнения памяти
  266. arrOfRequests[numOfRequests] = new Request(length,name, name, numOfRequests);// добавляем в массив запросов этот запрос
  267. // в конструктор передаем сколько бит надо заполнить, какими числами надо заполнить, какой номер потока котоый хочет это сделать, и под каким номером хранится этот запрос внутри самого потока
  268. if(Data.getInstance().isReady()) // в случае если память готова
  269. Data.getInstance().GetRequest(arrOfRequests[toSend++]); // отправляем последний неотправленный запрос (с индексом toSend )
  270.  
  271.  
  272.  
  273. numOfRequests++;//в любом случае (отправили запрос или нет) увеличиваем счетчик ( а если отпарвили еще и счетчик отправленных запросов toSend
  274. try {
  275. sleep(1000*length); //засыпает пропорционально отправленной длинне данных
  276. } catch (InterruptedException e) {
  277. // TODO Auto-generated catch block
  278. e.printStackTrace();
  279. }
  280. }
  281.  
  282.  
  283. else // в случае же если нуль, то удаляем( отменяем одну из операций )
  284. {
  285. int n = r.nextInt()%numOfRequests; // находим произвольно одну из предыдущих операций
  286. if(arrOfRequests[n] == null) // если она уже была отменена
  287. continue; // начинаем весь цикл заново
  288. if(Data.getInstance().isReady()) // если же нет проверяем готовность памяти
  289. Data.getInstance().GetCancel(name, n); // и посылаем запрос на удаление
  290. // что важно - здест отсутствует удаление запроса который был только что отменен забыл я это сделать
  291.  
  292. }
  293.  
  294. }
  295.  
  296. }
  297.  
  298.  
  299. }
  300.  
  301. class Stack <Type>
  302. {
  303. private Type[] mass = (Type[])new Object[50000];;// массив обьектов
  304. final int SIZE = 500; //масимальный развер
  305. int num = 0; //текущий индес последнего обьекта
  306. int first = 0; //при считывании элемента мы не сдвигаем все остальные элементы назад а просто пересохраняем индекс первого элемента
  307. // (считывается всегда элемент с индексом first а добавляется новый элемент в конец с индексом num
  308. int lastFind;
  309. Stack ()
  310. {
  311.  
  312. }
  313. int push(Type elem)
  314. {
  315.  
  316. if(num + 1 < 500)
  317. {
  318. mass[num++] = elem;
  319. return num;
  320. }
  321. else return -1;
  322. }
  323. public Type pop()
  324. {
  325. if(num > 0)
  326. return mass[first++];
  327. throw new ArrayIndexOutOfBoundsException(-1);
  328. }
  329. // под операцией подразумевается заполнение определнного куска памяти числами определенным потоком
  330. Operation Find(int ThreadNum, int numOper){ // для поиска операции получает номер потока и номер запроса-операции в этом потоке
  331.  
  332. for(int i = 0; i < num; i++)
  333. {
  334. if( ((Operation)mass[i]).ThreadNum() == ThreadNum &&
  335. ((Operation)mass[i]).num() == numOper)
  336. {
  337. lastFind = i;
  338. return ((Operation)mass[i]);
  339. }
  340.  
  341. }
  342. return null;
  343. }
  344. void KickLastFind(){ // удаляет последний найденный элемент методом Find и сдивгает массив
  345. for(int i = lastFind ; i < num-1; i++)
  346. mass[i] = mass[i+1];
  347. num--;
  348.  
  349.  
  350.  
  351. }
  352.  
  353. }
  354. public class Chief
  355. {
  356. public static void main (String args[])
  357. {
  358. BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // для считывания строки ридер
  359.  
  360. MyThread[] threads = new MyThread[500]; //массив потоков
  361. int numOfThreads = 1; // количество потоков (начиная с единицы чтобы не было потока с нулевым номером
  362. while(true)
  363. {
  364. String str = "";
  365. try {
  366. str = in.readLine(); // считываем строку
  367. } catch (IOException e) {
  368. // TODO Auto-generated catch block
  369. e.printStackTrace();
  370. }
  371. if(str.equals("+")) // если строка равна + то добавляем новый поток
  372. {
  373. threads[numOfThreads-1] = new MyThread(Integer.toString(numOfThreads));// добавляем в массив новый поток, передавая в качестве параметра (имени) номер текущего потока в массиве
  374. numOfThreads++;
  375.  
  376. }
  377. else // если строка не равна плюсу то закрываем файловый поток и завершаем программу (но завершается основной поток только все остальные остаются
  378. {
  379. try {
  380. file.getInstance().close();
  381. } catch (IOException e) {
  382. // TODO Auto-generated catch block
  383. e.printStackTrace();
  384. }
  385. break;
  386. }
  387.  
  388. }
  389.  
  390. }
  391. }
Add Comment
Please, Sign In to add comment