В проблеме, которую я пытаюсь решить, каждый поток должен прочитать весь файл (возможно, каждый поток будет доставлять свое содержимое другой задаче или любой другой цели). После его чтения поток должен немного засыпать, а затем попытаться прочитать файл снова, и только заданное количество (n) потоков должно читать файл. Моя попытка решить эту проблему с контролем количества работающих потоков приведена в приведенном ниже коде:
import java.util.*;
class Reader implements Runnable{
Thread t;
Controler c;
public Reader(Controler c){
t = new Thread(this);
this.c = c;
t.start();
}
public void run(){
Random ran = new Random();
int napTime;
while(true){
try{
w.intentarLeerArchivo(t);
//Specification says that each reader
//should wait a bit before trying to
//read the file again
napTime = ran.nextInt(1000);
t.sleep(napTime);
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
}
class Controler{
Random ran;
LinkedList <Reader> readers;
int n;
int count;
public Controler(int n){
readers = new LinkedList <Reader>();
this.n = n;
count = 0;
ran = new Random();
}
public synchronized void getPermission(){
try{
while(count >= n){
wait();
}
notify();
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
public synchronized void increaseCount(){
count++;
}
public synchronized void decreaseCount(){
count--;
System.out.println("There are " + count + " threads reading");
}
public void intentarLeerArchivo(Thread t){
int readTime = 1000;
try{
getPermission();
System.out.println("Thread " + t.getId() +" empezó a leer");
increaseCount();
t.sleep(readTime);
System.out.println("Thread " + t.getId() +" is reading");
System.out.println("Thread " + t.getId() + " finished reading");
decreaseCount();
} catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
class Initializer{
int numReaders;
int maxReaders;
public Initializer(int numReaders, int maxReaders){
this.numReaders = numReaders;
this.maxReaders = maxReaders;
}
public void init(){
Controler c = new Controler(maxReaders);
for(int i = 0; i < numReaders; i++){
new Reader(c);
}
}
}
public class FileShare{
public static void main(String [] args){
Initializer c = new Initializer(100, 50);
c.init();
}
}
Я написал несколько строк для отладки. Они печатают состояние каждого потока и количество потоков, которые читают, когда один из них заканчивает чтение. Но когда я запускаю программу, оказывается, что внезапно появляется больше потоков, читающих файл, чем предполагалось. Я предполагаю, что это как-то связано с моими манипуляциями с синхронизацией. Что я делаю неправильно?
Я бы так и поступил, но меня попросили заново изобрести колесо в качестве должности.




Когда поток находится в
while(...){wait()}
раздел вашей реализации, он ждет, пока кто-нибудь не уведомит его, чтобы продолжить. Прямо сейчас, когда вы заканчиваете ждать, вы сразу же уведомляете.
Подумайте об этом, если, войдя в систему, я уведомлю кого-нибудь, что должен прийти, он не будет ждать, пока я закончу, прежде чем войти. Вы хотите использовать уведомление, когда вы оставляете файл.
Спасибо! Вот и все!
Это может быть проблема X / Y / изобретение колеса заново. Java уже содержит класс, который отслеживает изменения в каталоге (включая его файлы). Рассмотрите возможность использования этого класса вместо того, чтобы пытаться реализовать свой собственный. docs.oracle.com/javase/tutorial/essential/io/notification.ht ml