我正在做一个迷宫,两个线程正在处理simultaneously.The问题,它们不能在同一时间共享相同的位置。我不知道我该怎么做。是否有可能知道它们下一步将移动到哪里,并防止其他线程移动到该位置?请给我一个想法。谢谢。
代码如下:
public int[][] visitedCell=new int[15][15]; // holds how many times visited for each cell
public boolean cntrl=true,repeat=true,end;
public int r=0;
public int cnt;
public boolean find;
public void decision(int posX,int posY){
int distanceToExit;
cnt=0; // holds how many cell is free around the cell which thread is on
r=0;
end=false; // checks robot found exit
find=false; // checks suitable cell found to move in next step
posX=posX/40; // all cells are 40*40 dimension.since it is divided 40 to find poisition
posY=posY/40; // found y position
int[][] neighbours={{posX,posY+1},{posX+1,posY+1},{posX+1,posY},{posX+1,posY-1},{posX,posY-1},{posX-1,posY-1},{posX-1,posY},{posX-1,posY+1}}; // all 8 neighbours of a cell
int[][] freeCellChoises = new int[8][2]; // holds free cells to move
int[][] distanceCell=new int[8][2];
for(int i=0;i<8;i++){ // checks which neighbour cells are free
if((neighbours[i][0] >0 && neighbours[i][0] <14) && (neighbours[i][1] >0 && neighbours[i][1] < 14) || (neighbours[i][0]==1 && neighbours[i][1]==14) || (neighbours[i][0]==14 && neighbours[i][1]==1) ) // [1,14] = enter position and [14,1]= exit position
{
if(Draw.paintArray[neighbours[i][0]][neighbours[i][1]]==0){// cell is free.it is eligible
freeCellChoises[cnt][0]=neighbours[i][0]; // load eligible cells this array
freeCellChoises[cnt][1]=neighbours[i][1];
distanceToExit=(int) Math.sqrt((Math.pow(neighbours[i][0]-560, 2)+Math.pow(neighbours[i][1]-40,2)));
distanceCell[cnt][0]=cnt;
distanceCell[cnt][1]=distanceToExit;
cnt++;}
}
} // eligible cells are ready anymore
if(Frame.radButSel==1){ // random movement
int no=rndm.nextInt(cnt); // choose one of the eligible cell randomly
x=freeCellChoises[no][0] * 40;
y=freeCellChoises[no][1] * 40;
}
if(Frame.radButSel==2){ // closed way movement ( find the most clodes cell to the exit ) .Exit is [14,1].So x must be max, y must be min to a cell has priority
int maxX=freeCellChoises[0][0];
int minY=freeCellChoises[0][1];
int selection1=0,selection2=0;
for(int i=0;i<cnt;i++){ // x i byk y si kck sec
if(freeCellChoises[i][0]> maxX){
maxX=freeCellChoises[i][0];
selection1=i;}
if(freeCellChoises[i][1]<minY){
minY=freeCellChoises[i][1];
selection2=i;
}
}
if(cnt!=0) // checks there is a priority cell
r=rndm.nextInt(2)+1; // selects one of the priority cell
if(r==1 && visitedCell[freeCellChoises[selection1][0]][freeCellChoises[selection1][1]] <2){ //selection1.same cell musnt be visited more than 2 times
x=freeCellChoises[selection1][0] * 40;
y=freeCellChoises[selection1][1] * 40;}
else if(r==2 && visitedCell[freeCellChoises[selection2][0]][freeCellChoises[selection2][1]] <2){//selection2
x=freeCellChoises[selection2][0] * 40;
y=freeCellChoises[selection2][1] * 40;}
else{ // applies when there is not any priority cell
System.out.println("oncelik yok");
int repeat =0;
while(repeat<cnt){
r=rndm.nextInt(cnt); // choose one of the eligible cell
x=freeCellChoises[r][0] * 40;
y=freeCellChoises[r][1] * 40;
if(visitedCell[freeCellChoises[r][0]][freeCellChoises[r][1]] <2){
repeat=10;
}
else
repeat++;
}System.out.println("x="+x+"y="+y);
}
}
if(Frame.radButSel==3){
}
if(x==560 && y==40){ // checks decided cell is exit point
Action.pool.shutdownNow();// thread finished
end=true;
Main.butAct++; // when butAct=2 , "RESULT" button will be active
timer.stopTime();} // stops time for the thread
distance=(int) Math.sqrt(Math.pow(x-560,2) + Math.pow(y-40, 2));// calculates distance between thread - exit}
public Action() throws InterruptedException{
pool=Executors.newFixedThreadPool(2); // two thread in the pool
robot1=new Robot(40,560); // starts enter position
robot2=new Robot(40,560); // starts enter position
pool.submit(robot1); // loads robot1 to pool
pool.submit(robot2);// loadss robot2 to pool
}
public void run() {
while(true){ // run threads always
try {
Frame.worker.pauseIfNeeded();} // checks whether pause button is pressed
catch (InterruptedException ex) {
Logger.getLogger(Robot.class.getName()).log(Level.SEVERE, null, ex);}
if(end==false){// not reach exit
try{
System.out.println(Thread.currentThread().getName());// displays current thread name
System.out.println("pozisyon x="+x+"y="+y);
decision(x,y); // thread makes decision to move
visitedCell[x/40][y/40]+=1; // increade number of visitide cell count for that cell in the array
visCell++; //increase visited cell count for the thread
Thread.sleep(300);} // thread sleeps for a while to observe movement changing
catch(Exception ex){
}
}
else{// found exit
Thread.currentThread().interrupt(); // Thread killed
if(Main.butAct==2)// after a thread found exit, checks if result button can be active anymore
Frame.button4.setEnabled(true); // activates result button
}
}//end while}
发布于 2011-12-11 04:34:29
或者你可以这样做。manager类知道两个线程的位置,moveTo方法检查它们是否在同一位置重合。
class MazeManager {
int x1, x2, y1, y2;
public synchronized boolean moveTo(int threadId, int x, int y) {
..
}
}发布于 2011-12-11 04:15:48
最简单的解决方案是以这样一种方式“划分”工作,即两个工作区域(要尝试的解决方案/路径)相互排斥。一种变通方法是拥有一个并发的位置集,每个线程在移动之前都会检查这些位置。
发布于 2011-12-11 04:31:39
你将不得不使用所谓的互斥的概念。在Java语言中,您必须使用synchronized关键字来完成这项工作。可以在1中看到一个简单的示例
public class SynchronizedCounter {
private int i = 0;
public synchronized void increment() {
i++;
}
public synchronized void decrement() {
i--;
}
public synchronized int value() {
return i;
}
}在这里您可以看到一段代码,它确保只有一个线程能够修改共享变量i的值。注意,代码使用this作为所谓的“锁对象”。您可以通过以下方式重写代码:
public class SynchronizedCounter {
private int i = 0;
public void increment() {
synchronized(this) {
i++;
}
}
public void decrement() {
synchronized(this) {
i--;
}
}
public int value() {
synchronized(this) {
return i;
}
}
}或者,您可能希望创建自己的锁对象并使用它:
public class SynchronizedCounter {
private int i = 0;
private Object lock = new Object();
public void increment() {
synchronized(lock) {
i++;
}
}
public void decrement() {
synchronized(lock) {
i--;
}
}
public int value() {
synchronized(lock) {
return i;
}
}
}现在,任意数量的线程都可以随机调用这个对象的方法,但是一次只有一个线程能够传递锁并进行实际的修改。
1
https://stackoverflow.com/questions/8459514
复制相似问题