Ahoj,
mohli byste se mi, prosím, kouknout na tento kod? Snažím se udělat něco podobného, jako je třída Executor v javě. Čili můžu vytvořit x vláken, které budou mít práci. V tomhle případě generují náhodná čísla a počítají průměr. Když práci dokončí, čekají/běží dál, dokud jim není další přidělena. Všechny vlákna jsou vypnuta pomocí metody cancel() ve Worker nebo inter() v Executor. A mám tam dvě metody "run" - jedna run a druhá "runy" - to jsou vlastně dvě má řešení, jedno obsahuje wait() a druhé je bez. Když chci zrušit vlákna s "run" - tak volám cancel, když "Runy", tak inter() v Executor. Poté tam je noty() - což vlastně započne znova práci, a setNumber - což započné práci pro tu metodu bez wait
Můj dotaz - jsou obě dvě řešení použitelná/správná? Lze to takto provéct?
Pomocí synchronized(this) by nemělo docházet k tomu, že více vláken bude se najednou dostávat k proměnné average, takže by ty výsledky měly být ok. Je to tak?
Mockrát díky
public class Worker extends Thread {
private int number;
private double average = 0;
private volatile boolean cancelled;
public Worker(int number) {
this.number = number;
cancelled = false;
}
public void run() {
synchronized (this) {
while (!cancelled) {
if (number > 0) {
for (int i = 0; i < number; i++) {
average += Math.random();
if (number - 1 == i) {
number = 0;
System.out.println(Thread.currentThread().getName() + " average is: " + average);
}
}
}
}
}
System.out.println(Thread.currentThread().getName() + " is cancelled...");
}
public void runy() {
synchronized (this) {
while (!cancelled) {
if (number > 0) {
for (int i = 0; i < number; i++) {
average += Math.random();
if (number - 1 == i) {
number = 0;
System.out.println(Thread.currentThread().getName() + " average is " + average);
try {
this.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
System.out.println("Thread interupted");
cancelled = true;
}
}
}
}
}
}
}
public void cancel() {
this.cancelled = true;
}
public void noty(int number) {
synchronized (this) {
this.notifyAll();
this.number = number;
}
}
public double getAverage() {
return this.average;
}
public void setNumber(int number) {
this.number = number;
}
public class Executor {
private List<Worker> activeThreads;
public Executor(){
activeThreads = new ArrayList<>();
}
public void createThreads(int number){
for(int i = 0; i < number; i++){
Worker worker = new Worker(1000000);
worker.setName("Vlákno " + i);
activeThreads.add(worker);
worker.start();
}
}
public void cancelThreads(){
activeThreads.forEach(t -> t.cancel());
}
public void startJob(int num){
activeThreads.forEach(t -> t.setNumber(num));
}
public void getActiveThreads(){
System.out.println(Thread.getAllStackTraces().keySet().size());
}
public void noti(int num){
activeThreads.forEach(t -> t.noty(num));
}
public void inter(){
activeThreads.forEach(t -> t.interrupt());
}