leetcode多线程

我们提供了一个类:

public class Foo {

public void one() { print("one"); }

public void two() { print("two"); }

public void three() { print("three"); }

}

三个不同的线程将会共用一个 Foo 实例。

线程 A 将会调用 one() 方法

线程 B 将会调用 two() 方法

线程 C 将会调用 three() 方法

请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。

第一种方法 countdownlatch方法

classFoo{

privateCountDownLatch c2=newCountDownLatch(1);

privateCountDownLatch c3=newCountDownLatch(1);

publicFoo(){

        }

publicvoidfirst(Runnable printFirst)throwsInterruptedException{

// printFirst.run() outputs "first". Do not change or remove this line.

            printFirst.run();

            c2.countDown();

        }

publicvoidsecond(Runnable printSecond)throwsInterruptedException{

            c2.await();

// printSecond.run() outputs "second". Do not change or remove this line.

            printSecond.run();

            c3.countDown();

        }

publicvoidthird(Runnable printThird)throwsInterruptedException{

            c3.await();

// printThird.run() outputs "third". Do not change or remove this line.

            printThird.run();

        }

    }

第二种方法 CAS

classFoo{

privateAtomicInteger c2=newAtomicInteger(0);

privateAtomicInteger c3=newAtomicInteger(0);

publicFoo(){

        }

publicvoidfirst(Runnable printFirst)throwsInterruptedException{

// printFirst.run() outputs "first". Do not change or remove this line.

            printFirst.run();

            c2.incrementAndGet();

        }

publicvoidsecond(Runnable printSecond)throwsInterruptedException{

// printSecond.run() outputs "second". Do not change or remove this line.

while(c2.get()!=1){}

            printSecond.run();

            c3.incrementAndGet();

        }

publicvoidthird(Runnable printThird)throwsInterruptedException{

// printThird.run() outputs "third". Do not change or remove this line.

while(c3.get()!=1){}

            printThird.run();

        }

    }

第三种方法 信号量

classFoo{

privateSemaphore c2=newSemaphore(0);

privateSemaphore c3=newSemaphore(0);

publicFoo(){

        }

publicvoidfirst(Runnable printFirst)throwsInterruptedException{

// printFirst.run() outputs "first". Do not change or remove this line.

            printFirst.run();

            c2.release();

        }

publicvoidsecond(Runnable printSecond)throwsInterruptedException{

// printSecond.run() outputs "second". Do not change or remove this line.

            c2.acquire();

            printSecond.run();

            c3.release();

        }

publicvoidthird(Runnable printThird)throwsInterruptedException{

// printThird.run() outputs "third". Do not change or remove this line.

            c3.acquire();

            printThird.run();

        }

}

第四种方法 synchronized方法

classFoo{

privatefinalObject o=newObject();

privateintstate=1;

publicFoo(){

        }

publicvoidfirst(Runnable printFirst)throwsInterruptedException{

// printFirst.run() outputs "first". Do not change or remove this line.

synchronized(o) {

                printFirst.run();

state=2;

                o.notifyAll();

            }

        }

publicvoidsecond(Runnable printSecond)throwsInterruptedException{

// printSecond.run() outputs "second". Do not change or remove this line.

synchronized(o) {

while(state!=2){

                    o.wait();

                }

                printSecond.run();

state=3;

                o.notifyAll();

            }

        }

publicvoidthird(Runnable printThird)throwsInterruptedException{

// printThird.run() outputs "third". Do not change or remove this line.

synchronized(o) {

while(state!=3){

                    o.wait();

                }

                printThird.run();

            }

        }

}

第五种方法 lock方法

classFoo{

privateReentrantLock lock=newReentrantLock();

privateCondition c2=lock.newCondition();

privateCondition c3=lock.newCondition();

privateintstate=1;

publicFoo(){

        }

publicvoidfirst(Runnable printFirst)throwsInterruptedException{

// printFirst.run() outputs "first". Do not change or remove this line.

try{

                lock.lock();

                printFirst.run();

                c2.signal();

state=2;

}finally{

                lock.unlock();

            }

        }

publicvoidsecond(Runnable printSecond)throwsInterruptedException{

// printSecond.run() outputs "second". Do not change or remove this line.

try{

                lock.lock();

while(state!=2){

                    c2.await();

                }

                printSecond.run();

state=3;

                c3.signal();

}finally{

                lock.unlock();

            }

        }

publicvoidthird(Runnable printThird)throwsInterruptedException{

// printThird.run() outputs "third". Do not change or remove this line.

try{

                lock.lock();

while(state!=3){

                    c3.await();

                }

                printThird.run();

}finally{

                lock.unlock();

            }

        }

    }

1115. 交替打印FooBar

我们提供一个类:

class FooBar {

public void foo() {

for (int i = 0; i < n; i++) {

print("foo");

}

}

public void bar() {

for (int i = 0; i < n; i++) {

print("bar");

}

}

}

两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。

请设计修改程序,以确保 "foobar" 被输出 n 次。

classFooBar{

privateintn;

privateObject lock=newObject();

privateintcount=1;

publicFooBar(intn){

this.n = n;

        }

publicvoidfoo(Runnable printFoo)throwsInterruptedException{

for(inti =0; i < n; i++) {

synchronized(lock) {

while(count!=1)lock.wait();

// printFoo.run() outputs "foo". Do not change or remove this line.

                    printFoo.run();

                    lock.notifyAll();

                    count--;

                }

            }

        }

publicvoidbar(Runnable printBar)throwsInterruptedException{

for(inti =0; i < n; i++) {

synchronized(lock) {

while(count!=0)lock.wait();

// printBar.run() outputs "bar". Do not change or remove this line.

                    printBar.run();

                    lock.notifyAll();

                    count++;

                }

            }

        }

    }

1116. 打印零与奇偶数

假设有这么一个类:

class ZeroEvenOdd {

public ZeroEvenOdd(int n) { ... }      // 构造函数

public void zero(printNumber) { ... }  // 仅打印出 0

public void even(printNumber) { ... }  // 仅打印出 偶数

public void odd(printNumber) { ... }   // 仅打印出 奇数

}

相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程:

线程 A 将调用 zero(),它只输出 0 。

线程 B 将调用 even(),它只输出偶数。

线程 C 将调用 odd(),它只输出奇数。

每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。

classZeroEvenOdd{

privateintn;

privateSemaphore zero=newSemaphore(1);

privateSemaphore odd=newSemaphore(0);

privateSemaphore even=newSemaphore(0);

publicZeroEvenOdd(intn){

this.n = n;

        }

// printNumber.accept(x) outputs "x", where x is an integer.

publicvoidzero(IntConsumer printNumber)throwsInterruptedException{

for(inti=1;i<=n;i++){

                zero.acquire();

printNumber.accept(0);

if((i&1)==1){

                    odd.release();

}else{

                    even.release();

                }

            }

        }

publicvoideven(IntConsumer printNumber)throwsInterruptedException{

for(inti=2;i<=n;i+=2){

                even.acquire();

                printNumber.accept(i);

                zero.release();

            }

        }

publicvoidodd(IntConsumer printNumber)throwsInterruptedException{

for(inti=1;i<=n;i+=2) {

                odd.release();

                printNumber.accept(i);

                zero.release();

            }

        }

    }

1117. H2O 生成

每次获取一个H,需要释放一个O,O需要获取2个,同时H释放两个

classH2O{

privateSemaphore h=newSemaphore(2);

privateSemaphore o=newSemaphore(0);

publicH2O(){

        }

publicvoidhydrogen(Runnable releaseHydrogen)throwsInterruptedException{

// releaseHydrogen.run() outputs "H". Do not change or remove this line.

            h.acquire();

            releaseHydrogen.run();

            o.release();

        }

publicvoidoxygen(Runnable releaseOxygen)throwsInterruptedException{

// releaseOxygen.run() outputs "O". Do not change or remove this line.

o.acquire(2);

            releaseOxygen.run();

h.release(2);

        }

    }

1195. 交替打印字符串

编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:

如果这个数字可以被 3 整除,输出 "fizz"。

如果这个数字可以被 5 整除,输出 "buzz"。

如果这个数字可以同时被 3 和 5 整除,输出 "fizzbuzz"。

classFizzBuzz{

privateintn;

privateReentrantLock lock=newReentrantLock();

privateCondition f=lock.newCondition();

privateCondition b=lock.newCondition();

privateCondition fb=lock.newCondition();

privateCondition nc=lock.newCondition();

privatebooleanstate=false;

publicFizzBuzz(intn){

this.n = n;

        }

// printFizz.run() outputs "fizz".

publicvoidfizz(Runnable printFizz)throwsInterruptedException{

for(inti=3;i<=n;i+=3){

                lock.lock();

try{

if(i %5!=0) {

while(!state){

                            f.await();

                        }

                        printFizz.run();

state=false;

                        nc.signal();

                    }

}finally{

                    lock.unlock();

                }

            }

        }

// printBuzz.run() outputs "buzz".

publicvoidbuzz(Runnable printBuzz)throwsInterruptedException{

for(inti=5;i<=n;i+=5){

                lock.lock();

try{

if(i%3!=0){

while(!state){

                            b.await();

                        }

                        printBuzz.run();

state=false;

                        nc.signal();

                    }

}finally{

                    lock.unlock();

                }

            }

        }

// printFizzBuzz.run() outputs "fizzbuzz".

publicvoidfizzbuzz(Runnable printFizzBuzz)throwsInterruptedException{

for(inti=15;i<=n;i+=15){

                lock.lock();

try{

while(!state){

                        fb.await();

                    }

                    printFizzBuzz.run();

state=false;

                    nc.signal();

}finally{

                    lock.unlock();

                }

            }

        }

// printNumber.accept(x) outputs "x", where x is an integer.

publicvoidnumber(IntConsumer printNumber)throwsInterruptedException{

for(inti=1;i<=n;i++){

                lock.lock();

try{

while(state){

                        nc.await();

                    }

if(i%3==0&&i%5==0){

                        fb.signal();

state=true;

                    }

elseif(i%3==0){

                        f.signal();

state=true;

}elseif(i%5==0){

                        b.signal();

state=true;

}else{

                        printNumber.accept(i);

                        nc.signal();

                    }

}finally{

                    lock.unlock();

                }

            }

        }

    }

1226. 哲学家进餐

classDiningPhilosophers{

privateReentrantLock[] locks=newReentrantLock[]{

newReentrantLock(),

newReentrantLock(),

newReentrantLock(),

newReentrantLock(),

newReentrantLock()

        };

privateSemaphore eatLimit=newSemaphore(4);

publicDiningPhilosophers(){

        }

// call the run() method of any runnable to execute its code

publicvoidwantsToEat(intphilosopher,

                              Runnable pickLeftFork,

                              Runnable pickRightFork,

                              Runnable eat,

                              Runnable putLeftFork,

                              Runnable putRightFork)throwsInterruptedException {

intleft=(philosopher+1)%5;

intright=philosopher;

            eatLimit.acquire();

            locks[left].lock();

            locks[right].lock();

            pickLeftFork.run();

            pickRightFork.run();

            eat.run();

            putLeftFork.run();

            putRightFork.run();

            locks[left].unlock();

            locks[right].unlock();

            eatLimit.release();

        }

    }

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容