首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >猜测同时运行的线程的下一个位置

猜测同时运行的线程的下一个位置
EN

Stack Overflow用户
提问于 2011-12-11 04:11:55
回答 5查看 183关注 0票数 1

我正在做一个迷宫,两个线程正在处理simultaneously.The问题,它们不能在同一时间共享相同的位置。我不知道我该怎么做。是否有可能知道它们下一步将移动到哪里,并防止其他线程移动到该位置?请给我一个想法。谢谢。

代码如下:

代码语言:javascript
复制
        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

}

代码语言:javascript
复制
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

}

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-12-11 04:34:29

或者你可以这样做。manager类知道两个线程的位置,moveTo方法检查它们是否在同一位置重合。

代码语言:javascript
复制
class MazeManager {
  int x1, x2, y1, y2;

  public synchronized boolean moveTo(int threadId, int x, int y) {
    ..
  }
}
票数 1
EN

Stack Overflow用户

发布于 2011-12-11 04:15:48

最简单的解决方案是以这样一种方式“划分”工作,即两个工作区域(要尝试的解决方案/路径)相互排斥。一种变通方法是拥有一个并发的位置集,每个线程在移动之前都会检查这些位置。

票数 1
EN

Stack Overflow用户

发布于 2011-12-11 04:31:39

你将不得不使用所谓的互斥的概念。在Java语言中,您必须使用synchronized关键字来完成这项工作。可以在1中看到一个简单的示例

代码语言:javascript
复制
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作为所谓的“锁对象”。您可以通过以下方式重写代码:

代码语言:javascript
复制
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;
    }
  }
}

或者,您可能希望创建自己的锁对象并使用它:

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8459514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档