Hallo,
ich habe eine Frage. Beim ausführen des Programms, entsteht ein Standbild vom Spiel. Normalerweise sollte sich die neue Generation der Zellen aktualisieren also es soll ein Wachstum entstehen. Warum bewegt sich das Bild beim ausführen nicht?
public class Application {
/* Size of the playground in X dimension */
public static final int DIM_X = 200;
/* Size of the playground in Y dimension */
public static final int DIM_Y = 200;
/* Probability threshold that a cell is initially being created */
public static final float ALIVE_PROBABILITY = 0.3125f;
/* Sleep time between every generation in milliseconds */
public static final int SLEEP = 200;
/**
* Creates an potentially unlimited stream of Cell objects. The stream uses
* random numbers between [0, 1] and the probability threshold whether a
* cell is created DEAD (random > p) or ALIVE (random <= p).
*
* @param p Cell alive probability threshold.
* @Return
*/
private static Stream<Cell> createCellStream(float p) {
Random random = new Random();
return Stream.generate(() -> {
int status = random.nextFloat() <= p ? Cell.ALIVE : Cell.DEAD;
return new Cell(status);
});
}
public static void main(String[] args) {
Stream<Cell> cellStream = createCellStream(ALIVE_PROBABILITY);
Playground playground = new Playground(DIM_X, DIM_Y, cellStream);
// Create and show the application window
ApplicationFrame window = new ApplicationFrame();
window.setVisible(true);
window.getContentPane().add(new PlaygroundComponent(playground));
// Create and start a LifeThreadPool with 50 threads
LifeThreadPool pool = new LifeThreadPool(50);
pool.start();
while (true) {
Life life = new Life(playground);
for (int xi = 0; xi < DIM_X; xi++) {
for (int yi = 0; yi < DIM_Y; yi++) {
int finalXi = xi;
int finalYi = yi;
// Submit new life.process() call as runnable to the pool
pool.submit(() -> life.process(playground.getCell(finalXi, finalYi), finalXi, finalYi));
}
}
// Wait for all threads to finish this generation
try {
pool.barrier();
} catch (InterruptedException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
// Submit switch to next generation for each cell and force a
// window repaint to update the graphics
pool.submit(() -> {
playground.asList().forEach(cell -> cell.nextGen());
window.repaint();
});
// Wait SLEEP milliseconds until the next generation
try {
Thread.sleep(SLEEP);
} catch (InterruptedException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class LifeThread extends Thread {
private final LifeThreadPool pool;
private boolean isInterrupted = false;
public LifeThread(LifeThreadPool pool) {
this.pool = pool;
}
/**
* Sets the interrupted flag, so that this thread stops after finishing
* the current task.
*/
@Override
public void interrupt() {
isInterrupted = true;
}
@Override
public void run() {
while (!isInterrupted) {
try {
// Holt die nächste Aufgabe aus dem TaskThreadPool und führt sie aus
Runnable task = pool.nextTask();
task.run();
} catch (InterruptedException e) {
// Unterbricht die weitere Ausführung des Threads bei einer InterruptedException
break;
}
}
}
}
public class LifeThreadPool {
private final Queue<Runnable> tasks = new LinkedList<>();
private final int numThreads;
private final LifeThread[] threads;
public LifeThreadPool(int numThreads) {
this.numThreads = numThreads;
this.threads = new LifeThread[numThreads];
}
public synchronized void barrier() throws InterruptedException {
while (!tasks.isEmpty()) {
wait();
}
}
public synchronized void interrupt() {
for (LifeThread thread : threads) {
thread.interrupt();
}
}
public synchronized void joinAndExit() throws InterruptedException {
barrier();
interrupt();
}
public synchronized void submit(Runnable task) {
tasks.offer(task);
notifyAll();
}
public synchronized Runnable nextTask() throws InterruptedException {
while (tasks.isEmpty()) {
wait();
}
return tasks.poll();
}
public void start() {
for (int i = 0; i < numThreads; i++) {
threads = new LifeThread(this);
threads.start();
}
}
}
ich habe eine Frage. Beim ausführen des Programms, entsteht ein Standbild vom Spiel. Normalerweise sollte sich die neue Generation der Zellen aktualisieren also es soll ein Wachstum entstehen. Warum bewegt sich das Bild beim ausführen nicht?
public class Application {
/* Size of the playground in X dimension */
public static final int DIM_X = 200;
/* Size of the playground in Y dimension */
public static final int DIM_Y = 200;
/* Probability threshold that a cell is initially being created */
public static final float ALIVE_PROBABILITY = 0.3125f;
/* Sleep time between every generation in milliseconds */
public static final int SLEEP = 200;
/**
* Creates an potentially unlimited stream of Cell objects. The stream uses
* random numbers between [0, 1] and the probability threshold whether a
* cell is created DEAD (random > p) or ALIVE (random <= p).
*
* @param p Cell alive probability threshold.
* @Return
*/
private static Stream<Cell> createCellStream(float p) {
Random random = new Random();
return Stream.generate(() -> {
int status = random.nextFloat() <= p ? Cell.ALIVE : Cell.DEAD;
return new Cell(status);
});
}
public static void main(String[] args) {
Stream<Cell> cellStream = createCellStream(ALIVE_PROBABILITY);
Playground playground = new Playground(DIM_X, DIM_Y, cellStream);
// Create and show the application window
ApplicationFrame window = new ApplicationFrame();
window.setVisible(true);
window.getContentPane().add(new PlaygroundComponent(playground));
// Create and start a LifeThreadPool with 50 threads
LifeThreadPool pool = new LifeThreadPool(50);
pool.start();
while (true) {
Life life = new Life(playground);
for (int xi = 0; xi < DIM_X; xi++) {
for (int yi = 0; yi < DIM_Y; yi++) {
int finalXi = xi;
int finalYi = yi;
// Submit new life.process() call as runnable to the pool
pool.submit(() -> life.process(playground.getCell(finalXi, finalYi), finalXi, finalYi));
}
}
// Wait for all threads to finish this generation
try {
pool.barrier();
} catch (InterruptedException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
// Submit switch to next generation for each cell and force a
// window repaint to update the graphics
pool.submit(() -> {
playground.asList().forEach(cell -> cell.nextGen());
window.repaint();
});
// Wait SLEEP milliseconds until the next generation
try {
Thread.sleep(SLEEP);
} catch (InterruptedException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class LifeThread extends Thread {
private final LifeThreadPool pool;
private boolean isInterrupted = false;
public LifeThread(LifeThreadPool pool) {
this.pool = pool;
}
/**
* Sets the interrupted flag, so that this thread stops after finishing
* the current task.
*/
@Override
public void interrupt() {
isInterrupted = true;
}
@Override
public void run() {
while (!isInterrupted) {
try {
// Holt die nächste Aufgabe aus dem TaskThreadPool und führt sie aus
Runnable task = pool.nextTask();
task.run();
} catch (InterruptedException e) {
// Unterbricht die weitere Ausführung des Threads bei einer InterruptedException
break;
}
}
}
}
public class LifeThreadPool {
private final Queue<Runnable> tasks = new LinkedList<>();
private final int numThreads;
private final LifeThread[] threads;
public LifeThreadPool(int numThreads) {
this.numThreads = numThreads;
this.threads = new LifeThread[numThreads];
}
public synchronized void barrier() throws InterruptedException {
while (!tasks.isEmpty()) {
wait();
}
}
public synchronized void interrupt() {
for (LifeThread thread : threads) {
thread.interrupt();
}
}
public synchronized void joinAndExit() throws InterruptedException {
barrier();
interrupt();
}
public synchronized void submit(Runnable task) {
tasks.offer(task);
notifyAll();
}
public synchronized Runnable nextTask() throws InterruptedException {
while (tasks.isEmpty()) {
wait();
}
return tasks.poll();
}
public void start() {
for (int i = 0; i < numThreads; i++) {
threads = new LifeThread(this);
threads.start();
}
}
}