【问题标题】:How to find why my Java semaphore is not working如何找到我的 Java 信号量不起作用的原因
【发布时间】:2019-11-28 18:09:55
【问题描述】:

我用线程和信号量编写了交通规则代码。

我认为我的代码没问题,但它不起作用。我的意思是它不会锁定我在第一个线程下写的第二个线程。我怎样才能找到我的错误?为什么这不锁定我的第二个线程?

我想看到这个结果: 我将有 6 辆车在交通中。 3 辆车在一条路线上(坐标不同),另外 3 辆车在另一条路线上(坐标不同)。比如A坐标是5,B是10,C是15。

相反,D 是-6,E 是-11,F 是-16。有路口。如果 A、B 和 C 车点正在减少(每两秒它们协调减少 1 减 1)。他们想要达到“upTarget”,例如 3。并且 D、E、F 坐标一一增加以达到 -3。如果 A 在 D 到达他的左目标(到 -3)之前到达上目标(到 3),所有左行将等到上行离开 0,0 坐标

我的意思是如果A达到3,那么A B C线将绿灯熄灭,D,E,F将等待它们直到C坐标为0

主类

package sample;

import java.util.Scanner;
import java.util.concurrent.Semaphore;

public class Main {
    public static int x1,x2,x3,y1,y2,y3,upTarget,leftTarget;

    public static void main(String[] args) throws InterruptedException{

        Scanner obj=new Scanner(System.in);

        System.out.println("Insert coordinant of A");
        x1=obj.nextInt();
        System.out.println("Insert coordinant of B");
        x2=obj.nextInt();
        System.out.println("Insert coordinant of C");
        x3=obj.nextInt();

        System.out.println("Insert coordinant of D");
        y1=obj.nextInt();
        System.out.println("Insert coordinant of E");
        y2=obj.nextInt();
        System.out.println("Insert coordinant of F");
        y3=obj.nextInt();

        System.out.println("Insert up target level");
        upTarget=obj.nextInt();

        System.out.println("Insert left target level");
        leftTarget=obj.nextInt();

        System.out.println("Traffic was start");
        Semaphore sem=new Semaphore(1);


        Thread t1=new MyBackend(sem,x1, x2, x3, upTarget, y1, y2, y3, leftTarget,"A");
        Thread t2=new MyBackend(sem,x1, x2, x3, upTarget, y1, y2, y3, leftTarget,"B");





        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }


}

我的后端代码 => 我的线程类

   import java.util.concurrent.Semaphore;

public class MyBackend extends Thread{
     Semaphore sem;
    private int x1,x2,x3,y1,y2,y3,upTarget,leftTarget;
    private String value;

    public MyBackend(Semaphore sem,int x1,int x2,int x3,int upTarget,int y1,int y2,int y3,int leftTarget,String value){
        super(value);
        this.sem=sem;
        this.x1=x1;
        this.x2=x2;
        this.x3=x3;
        this.y1=y1;
        this.y2=y2;
        this.y3=y3;
        this.upTarget=upTarget;
        this.leftTarget=leftTarget;
        this.value=value;
    }

    @Override
    public void run() {
        System.out.println("yeeeeeeeeeeeeeeeeeeeeeeeeeee"+sem.availablePermits());
        if(this.getName().equals("A")){
            try{

                while(x3>=0){
                    x1=x1-1;
                    x2=x2-1;
                    x3=x3-1;
                    Thread.sleep(2000);
                    System.out.println("A coordinate "+x1);
                    System.out.println("B coordinate "+x2);
                    System.out.println("C coordinate "+x3);

                    if(x1==upTarget){
                        sem.acquire();
                        System.out.println("yeeeeeeeeeeeeeeeeeeeeeeeeeee"+sem.availablePermits());
                        System.out.println("First line was reached!!!");
                    }
                }

            }catch(Exception e){}
            sem.release();
        }
        else {
            try{
                while(y3<=0){
                    y1=y1+1;
                    y2=y2+1;
                    y3=y3+1;
                    Thread.sleep(2000);
                    System.out.println("D coordinate "+y1);
                    System.out.println("E coordinate "+y2);
                    System.out.println("F coordinate "+y3);

                    if(y3==leftTarget){
                        sem.acquire();
                        System.out.println("Second line was reached!!!");
                    }
                }
            }catch(Exception e){}
            sem.release();
        }    }
}

【问题讨论】:

  • 你在观察什么,你到底期待什么?注意分享任何输出!
  • 我将有 6 辆车在路上行驶。 3 辆车在一条路线上(坐标不同),另外 3 辆车在另一条路线上(坐标不同)。例如,A 坐标为 5,B 为 10,C 为 15。相反,D 为 -6,E 为 -11,F 为 -16。有路口。如果 A、B 和 C 车点正在减少(每两秒它们协调减少 1 减 1)。他们想达到“upTarget”,例如 3。 D、E、F 坐标一一递增以达到 -3。如果 A 在 D 到达左目标(到 -3)之前到达上目标(到 3),则所有左行将等到上行离开 0,0 坐标。
  • 我的意思是如果 A 达到 3 则 A B C 线将绿灯熄灭,D,E,F 将等待它们直到 C 坐标为 0

标签: java multithreading semaphore


【解决方案1】:

您的代码工作正常,信号量工作正常。请在代码中更改线程 B 的 while 循环以添加更多 system.out.println() 如下所示,并查看当线程 A 获取信号量时,线程 B 实际上已挂起(如预期的那样)。


                while(y3<=0){
                    y1=y1+1;
                    y2=y2+1;
                    y3=y3+1;
                    Thread.sleep(2000);
                    System.out.println("D coordinate "+y1);
                    System.out.println("E coordinate "+y2);
                    System.out.println("F coordinate "+y3);

                    if(y3==leftTarget){
                        System.out.println("Thread B acquiring sem: "+sem.availablePermits() + "If this is 0, D,E and F should hang");
                        sem.acquire();
                        System.out.println("Semaphore acquired, continue thread B for D, E and F"+sem.availablePermits());
                        System.out.println("Second line was reached!!!");
                    }
                }

如果您期待其他内容,请澄清。

更新

根据您的评论,我认为您可以添加另一个 if 条件以检查信号量是否已被其他线程获取,然后更改坐标如下;

先设置一个静态同步变量,显示哪个线程先获取信号量。

import java.util.concurrent.Semaphore;

    public class MyBackend extends Thread{
         Semaphore sem;
        private volatile String acquiredBy = null;
        private int x1,x2,x3,y1,y2,y3,upTarget,leftTarget;
        private String value;

        public MyBackend(Semaphore sem,int x1,int x2,int x3,int upTarget,int y1,int y2,int y3,int leftTarget,String value){
            super(value);
            this.sem=sem;
            this.x1=x1;
            this.x2=x2;
            this.x3=x3;
            this.y1=y1;
            this.y2=y2;
            this.y3=y3;
            this.upTarget=upTarget;
            this.leftTarget=leftTarget;
            this.value=value;
        }

        @Override
        public void run() {
            System.out.println("yeeeeeeeeeeeeeeeeeeeeeeeeeee"+sem.availablePermits());
            if(this.getName().equals("A")){
                try{

                    while(x3>=0){
                        if(acquiredBy != null && !acquiredBy.equals(this.getName())){
                              sem.acquire();
                        }
                        x1=x1-1;
                        x2=x2-1;
                        x3=x3-1;
                        Thread.sleep(2000);
                        System.out.println("A coordinate "+x1);
                        System.out.println("B coordinate "+x2);
                        System.out.println("C coordinate "+x3);

                        if(x1==upTarget){
                            sem.acquire();
                            acquiredBy = this.getName();

                             System.out.println("yeeeeeeeeeeeeeeeeeeeeeeeeeee"+sem.availablePermits());
                            System.out.println("First line was reached!!!");
                        }
                    }

                }catch(Exception e){}
                sem.release();
            }
            else {
                try{
                    while(y3<=0){
                        if(acquiredBy != null &&  !acquiredBy.equals(this.getName())){
                              sem.acquire();
                        }
                        y1=y1+1;
                        y2=y2+1;
                        y3=y3+1;
                        Thread.sleep(2000);
                        System.out.println("D coordinate "+y1);
                        System.out.println("E coordinate "+y2);
                        System.out.println("F coordinate "+y3);

                        if(y3==leftTarget){
                            sem.acquire();
                            acquiredBy = this.getName();
                            System.out.println("Second line was reached!!!");
                        }
                    }
                }catch(Exception e){}
                sem.release();
            }    }
    }

这应该可行!

【讨论】:

  • 这行不通!我想要的结果是,如果 x1=3 然后锁定第二路的汽车(D,E,F)并继续第 1 行到他的工作。如果第 1 行中的最后一辆车(x3)等于 0,则释放 D E F 汽车的锁定那辆车将继续前进。你明白我的意思了吗?用户正确地给 A B C D E F 数字 5,10,15,-7,-12,-17。 A、B、C 车点要达到 3(上目标),反之 E、D、F 想达到 -3(左目标)。当哪条线路的车到达他的目标时,另一路的车协调会锁定。
  • 我根据您的评论更新了我的答案。请看一下
  • 部分输出 A坐标 4 B坐标 9 D坐标 -6 E坐标 -11 F坐标 -16 C坐标 14 D坐标 -5 E坐标 -10 F坐标 -15 A坐标 3 B坐标8 C 坐标 13 yeeeeeeeeeeeeeeeeeeeeeeeee0 到达第一行!!! D坐标-4 E坐标-9 F坐标-14 A坐标2 B坐标7 C坐标12 A坐标1 B坐标6 C坐标11
  • 将 Thread.sleep() 添加到两个 while 循环的第一行。应该没问题的。
  • 正在发生的事情是线程 a 获得了信号量,但同时线程 b 增加了 d、e 和 f 的坐标。如果不调用 sem.acquire,就无法停止线程 b 的工作,我们在坐标更新之前正在执行此操作。老实说,您最终需要重新考虑解决问题的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
相关资源
最近更新 更多