java多线程编程实现矩阵_用Java设计多线程矩阵

我有一个矩阵,实现了John Conway的生命模拟器,其中每个单元代表生命或缺乏生命.

每个生命周期都遵循以下规则:

>任何活着的邻居少于两个的活细胞就会死亡,就像人口不足一样.

>任何有两三个活邻居的活细胞都会留在下一代.

>任何有三个以上活着的邻居的活细胞都会死亡,就像过度拥挤一样.

>任何具有正好三个活邻居的死细胞都成为活细胞,就好像通过繁殖一样.

每个单元格都有一个线程,可以按照上面列出的规则执行更改.

我已经实现了这些类:

import java.util.Random;

public class LifeMatrix {

Cell[][] mat;

public Action currentAction = Action.WAIT_FOR_COMMAND;

public Action changeAction;

public enum Action {

CHECK_NEIGHBORS_STATE,

CHANGE_LIFE_STATE,

WAIT_FOR_COMMAND

}

// creates a life matrix with all cells alive or dead or random between dead or alive

public LifeMatrix(int length, int width) {

mat = new Cell[length][width];

for (int i = 0; i < length; i++) { // populate the matrix with cells randomly alive or dead

for (int j = 0; j < width; j++) {

mat[i][j] = new Cell(this, i, j, (new Random()).nextBoolean());

mat[i][j].start();

}

}

}

public boolean isValidMatrixAddress(int x, int y) {

return x >= 0 && x < mat.length && y >= 0 && y < mat[x].length;

}

public int getAliveNeighborsOf(int x, int y) {

return mat[x][y].getAliveNeighbors();

}

public String toString() {

String res = "";

for (int i = 0; i < mat.length; i++) { // populate the matrix with cells randomly alive or

// dead

for (int j = 0; j < mat[i].length; j++) {

res += (mat[i][j].getAlive() ? "+" : "-") + " ";

}

res += "\n";

}

return res;

}

public void changeAction(Action a) {

// TODO Auto-generated method stub

currentAction=a;

notifyAll(); //NOTIFY WHO??

}

}

/**

* Class Cell represents one cell in a life matrix

*/

public class Cell extends Thread {

private LifeMatrix ownerLifeMat; // the matrix owner of the cell

private boolean alive;

private int xCoordinate, yCoordinate;

public void run() {

boolean newAlive;

while (true) {

while (! (ownerLifeMat.currentAction==Action.CHECK_NEIGHBORS_STATE)){

synchronized (this) {//TODO to check if correct

try {

wait();

} catch (InterruptedException e) {

System.out.println("Interrupted while waiting to check neighbors");

}}

}

// now check neighbors

newAlive = decideNewLifeState();

// wait for all threads to finish checking their neighbors

while (! (ownerLifeMat.currentAction == Action.CHANGE_LIFE_STATE)) {

try {

wait();

} catch (InterruptedException e) {

System.out.println("Interrupted while waiting to change life state");

};

}

// all threads finished checking neighbors now change life state

alive = newAlive;

}

}

// checking the state of neighbors and

// returns true if next life state will be alive

// returns false if next life state will be dead

private boolean decideNewLifeState() {

if (alive == false && getAliveNeighbors() == 3)

return true; // birth

else if (alive

&& (getAliveNeighbors() == 0 || getAliveNeighbors() == 1)

|| getAliveNeighbors() >= 4)

return false; // death

else

return alive; // same state remains

}

public Cell(LifeMatrix matLifeOwner, int xCoordinate, int yCoordinate, boolean alive) {

this.ownerLifeMat = matLifeOwner;

this.xCoordinate = xCoordinate;

this.yCoordinate = yCoordinate;

this.alive = alive;

}

// copy constructor

public Cell(Cell c, LifeMatrix matOwner) {

this.ownerLifeMat = matOwner;

this.xCoordinate = c.xCoordinate;

this.yCoordinate = c.yCoordinate;

this.alive = c.alive;

}

public boolean getAlive() {

return alive;

}

public void setAlive(boolean alive) {

this.alive = alive;

}

public int getAliveNeighbors() { // returns number of alive neighbors the cell has

int res = 0;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate - 1].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate - 1, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate - 1][yCoordinate + 1].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate][yCoordinate - 1].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate][yCoordinate + 1].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate - 1) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate - 1].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate].alive)

res++;

if (ownerLifeMat.isValidMatrixAddress(xCoordinate + 1, yCoordinate + 1) && ownerLifeMat.mat[xCoordinate + 1][yCoordinate + 1].alive)

res++;

return res;

}

}

public class LifeGameLaunch {

public static void main(String[] args) {

LifeMatrix lifeMat;

int width, length, populate, usersResponse;

boolean userWantsNewGame = true;

while (userWantsNewGame) {

userWantsNewGame = false; // in order to finish the program if user presses

// "No" and not "Cancel"

width = Integer.parseInt(JOptionPane.showInputDialog(

"Welcome to John Conway's life simulator! \n"

+ "Please enter WIDTH of the matrix:"));

length = Integer.parseInt(JOptionPane.showInputDialog(

"Welcome to John Conway's life simulator! \n"

+ "Please enter LENGTH of the matrix:"));

lifeMat = new LifeMatrix(length, width);

usersResponse = JOptionPane.showConfirmDialog(null, lifeMat + "\nNext cycle?");

while (usersResponse == JOptionPane.YES_OPTION) {

if (usersResponse == JOptionPane.YES_OPTION) {

lifeMat.changeAction(Action.CHECK_NEIGHBORS_STATE);

}

else if (usersResponse == JOptionPane.NO_OPTION) {

return;

}

// TODO leave only yes and cancel options

usersResponse = JOptionPane.showConfirmDialog(null, lifeMat + "\nNext cycle?");

}

if (usersResponse == JOptionPane.CANCEL_OPTION) {

userWantsNewGame = true;

}

}

}

}

我的麻烦是同步线程:

每个单元格(一个线程)必须在所有线程检查其邻居之后才改变其生命/死亡状态.用户将通过单击按钮调用每个下一个生命周期.

从run()方法可以理解,我的逻辑是让每个单元(线程)运行并等待由LifeMatrix类中的变量currentAction表示的正确动作状态,并继续执行所需的动作.

我挣扎的是如何将这些消息传递给线程以了解何时等待以及何时执行下一个操作?

只要每个单元格都使用单独的线程实现,任何改变程序设计的建议都是非常受欢迎的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值