刷题记录
看了下leetcode,工作之后其实只刷了两百道左右,有一点怠惰。最近要疯狂刷题,练一下手感,记录一下各个题型的刷题记录。
多线程
- lettcode 1114 按序打印
首先想到的就是使用信号量来解决:
class Foo {
private Semaphore firsteSmaphore;
private Semaphore secondSmaphore;
private Semaphore thirdSmaphore;
public Foo() {
firsteSmaphore = new Semaphore(1);
secondSmaphore = new Semaphore(0);
thirdSmaphore = new Semaphore(0);
}
public void first(Runnable printFirst) throws InterruptedException {
firsteSmaphore.acquire();
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
secondSmaphore.release();
}
public void second(Runnable printSecond) throws InterruptedException {
secondSmaphore.acquire();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
thirdSmaphore.release();
}
public void third(Runnable printThird) throws InterruptedException {
thirdSmaphore.acquire();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
代码也可以优化一下:
class Foo {
private Semaphore semaphore12;
private Semaphore semaphore23;
public Foo() {
semaphore12 = new Semaphore(0);
semaphore23 = new Semaphore(0);
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
semaphore12.release();
}
public void second(Runnable printSecond) throws InterruptedException {
semaphore12.acquire();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
semaphore23.release();
}
public void third(Runnable printThird) throws InterruptedException {
semaphore23.acquire();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
还可以基于原子类来实现,其实本质上都是利用 AQS:
class Foo {
private AtomicInteger firstAtomicInteger;
private AtomicInteger secondAtomicInteger;
public Foo() {
firstAtomicInteger = new AtomicInteger(0);
secondAtomicInteger = new AtomicInteger(0);
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
firstAtomicInteger.incrementAndGet();
}
public void second(Runnable printSecond) throws InterruptedException {
while(firstAtomicInteger.get() != 1) {
// waiting
}
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
secondAtomicInteger.incrementAndGet();
}
public void third(Runnable printThird) throws InterruptedException {
while(secondAtomicInteger.get() != 1) {
// waiting
}
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
2. 1115 交替打印 FooBar
// 使用 Semaphore
class FooBar {
private int n;
private Semaphore fooSemaphore;
private Semaphore barSemaphore;
public FooBar(int n) {
this.n = n;
fooSemaphore = new Semaphore(1);
barSemaphore = new Semaphore(0);
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
fooSemaphore.acquire();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
barSemaphore.release();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
barSemaphore.acquire();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
fooSemaphore.release();
}
}
}
// 使用阻塞队列
class FooBar {
private int n;
private BlockingQueue<Integer> fooBlockingQueue;
private BlockingQueue<Integer> barBlockingQueue;
public FooBar(int n) {
this.n = n;
fooBlockingQueue = new LinkedBlockingQueue<>(1);
barBlockingQueue = new LinkedBlockingQueue<>(1);
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
fooBlockingQueue.put(i);
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
barBlockingQueue.put(i);
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
barBlockingQueue.take();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
fooBlockingQueue.take();
}
}
}