Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 锁定两个方法,但允许一个运行多线程_Java_C#_Multithreading_Thread Safety_Locking - Fatal编程技术网

Java 锁定两个方法,但允许一个运行多线程

Java 锁定两个方法,但允许一个运行多线程,java,c#,multithreading,thread-safety,locking,Java,C#,Multithreading,Thread Safety,Locking,我有两种方法: Foo(){…} Bar(){…} 我希望创建一个锁定,以便: 当有一个线程在Foo中运行时,线程将被锁定在Bar上,并且在Foo方法中没有线程之前无法运行 Foo中可以同时运行多个线程 简单地说,锁定:“不允许同时运行Foo和Bar,但允许Foo或Bar与多个线程一起运行” 注意:简单锁定不会起作用,因为它会支持条件1,但不会支持条件2。您只需要确保没有人在执行其他方法,您可以通过计算每个方法的线程数来存档。 我没有使用锁,只是等待设置和同步 int numFoo = 0; i

我有两种方法:

Foo(){…} Bar(){…}

我希望创建一个锁定,以便:

  • 当有一个线程在Foo中运行时,线程将被锁定在Bar上,并且在Foo方法中没有线程之前无法运行

  • Foo中可以同时运行多个线程

  • 简单地说,锁定:“不允许同时运行Foo和Bar,但允许Foo或Bar与多个线程一起运行”


    注意:简单锁定不会起作用,因为它会支持条件1,但不会支持条件2。

    您只需要确保没有人在执行其他方法,您可以通过计算每个方法的线程数来存档。 我没有使用锁,只是等待设置和同步

    int numFoo = 0;
    int numBar = 0;
    
    void foo(){
        enter(0);
        //stuff
        leave(0);
    }
    
    void bar(){
        enter(1);
        //Stuff
        leave(1);
    }
    
    //Synchronized makes no more than one thread can run this simultaneously, so they wont be any race condition
    synchronized void enter(int id){
        //If it was foo entering
        if (id == 0){
            while(numBar != 0)//Waits until theres none executing bar
                try {
                    this.wait();
                } catch (InterruptedException e) {e.printStackTrace();}
            numFoo++;//Enters
        }
        else{
            while(numFoo !=0)//Waits until none executes foo
                try { 
                    this.wait();
                } catch (InterruptedException e) { e.printStackTrace();}
            numBar++;//Enters
        }
    }
    
    synchronized void leave(int id){
        if (id == 0){
            numFoo--;
            if(numFoo == 0)//If it was the last executing foo unlocks the others
                this.notifyAll();
            }
        else{
            numBar--;
            if(numBar == 0)//If it was the last executing bar unlocks the others
                this.notifyAll();
        }
    }
    
    “while(numbar!=0)this.wait()”这是必要的,因为notifyAll()是如何工作的。
    如果没有它,可能会发生另一个线程在我们解锁并试图进入foo的线程到达foo++之前开始执行bar,导致同时执行bar和foo。

    也许你应该描述你的问题,而不是用一个例子来演示你想做什么。如果一个线程想进入foo,而另一个线程已经在运行bar呢?你不能用一个锁,而是用两个锁。在酒吧中设置傻瓜锁,在foo中设置酒吧锁。不过,您需要小心避免死锁。