class Foo {
private volatile int a=1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
while(a!=1){
}
printFirst.run();
a=2;
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
while(a!=2){
}
printSecond.run();
a=3;
}
public void third(Runnable printThird) throws InterruptedException {
// printThird.run() outputs "third". Do not change or remove this line.
while(a!=3){
}
printThird.run();
}
}
自选锁耗费cpu资源
Condition:
用condition await()方法阻塞
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class FooBar {
private int n;
private Lock lock=new ReentrantLock();
Condition a=lock.newCondition();
Condition b=lock.newCondition();
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
if(i==0){
printFoo.run();
b.signal();
}
lock.lock();
try {
a.await();
printFoo.run();
b.signal();
} catch (Exception e) {
//TODO: handle exception
} finally{
lock.unlock();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
b.await();
printBar.run();
a.signal();
} catch (Exception e) {
//TODO: handle exception
} finally{
lock.unlock();
}
}
}
}
Lock+Condition:
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.IntConsumer;
class ZeroEvenOdd {
private int n;
private static volatile int x=0;
private Lock lock=new ReentrantLock();
private Condition zero=lock.newCondition();
private Condition even=lock.newCondition();
private Condition odd=lock.newCondition();
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for(int i=0;i<n;i++){
lock.lock();
try {
while(x!=0){
zero.await();
}
printNumber.accept(0);
if(i%2==0){
x=1;
odd.signal();
}else{
x=2;
even.signal();
}
} catch (Exception e) {
//TODO: handle exception
}finally{
lock.unlock();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
int k=n;
if(k%2==0){
k=k+1;
}
for(int i=2;i<k;i+=2){
lock.lock();
try{
while(x!=2){
even.await();
}
printNumber.accept(i);
x=0;
zero.signal();
}catch(Exception e){
}finally{
lock.unlock();
}
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
int k=n;
if(k%2==1){
k=k+1;
}
for(int i=1;i<k;i+=2){
lock.lock();
try{
while(x!=1){
odd.await();
}
printNumber.accept(i);
x=0;
zero.signal();
}catch(Exception e){
}finally{
lock.unlock();
}
}
}
}
Semphore:
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.IntConsumer;
class ZeroEvenOdd {
private int n;
private Semaphore zero = new Semaphore(1);
private Semaphore odd = new Semaphore(0);
private Semaphore even = new Semaphore(0);
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 0; i < n; i++) {
zero.acquire();
printNumber.accept(0);
if (i % 2 == 0) {
odd.release();
} else {
even.release();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 2; i <= n; i += 2) {
even.acquire();
printNumber.accept(i);
zero.release();
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i += 2) {
odd.acquire();
printNumber.accept(i);
zero.release();
}
}
public static void main(String[] args) {
ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(10);
IntConsumer intConsumer = new IntConsumer() {
@Override
public void accept(int value) {
// TODO Auto-generated method stub
System.out.println(value);
}
};
new Thread(() -> {
try {
zeroEvenOdd.zero(intConsumer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
zeroEvenOdd.odd(intConsumer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
zeroEvenOdd.even(intConsumer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
}
LockSupport:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;
class H2O {
private volatile int hc=0;
private volatile int oc=0;
Semaphore h=new Semaphore(2);
Semaphore o=new Semaphore(1);
public H2O() {
}
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
// releaseHydrogen.run() outputs "H". Do not change or remove this line.
h.acquire();
releaseHydrogen.run();
hc++;
if(oc==1&&hc==2){
oc=0;
hc=0;
o.release();
h.release();
h.release();
}
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
// releaseOxygen.run() outputs "O". Do not change or remove this line.
o.acquire();
releaseOxygen.run();
oc++;
if(oc==1&&hc==2){
oc=0;
hc=0;
o.release();
h.release();
h.release();
}
}
}
import java.util.concurrent.Semaphore;
import java.util.function.IntConsumer;
class FizzBuzz {
private int n;
private Semaphore fizz=new Semaphore(0);
private Semaphore buzz=new Semaphore(0);
private Semaphore fizzbuzz=new Semaphore(0);
private Semaphore number=new Semaphore(1);
public FizzBuzz(int n) {
this.n = n;
}
// printFizz.run() outputs "fizz".
public void fizz(Runnable printFizz) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%3==0&&i%15!=0){
fizz.acquire();
printFizz.run();
f(i+1);
}
}
}
// printBuzz.run() outputs "buzz".
public void buzz(Runnable printBuzz) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%5==0&&i%15!=0){
buzz.acquire();
printBuzz.run();
f(i+1);
}
}
}
// printFizzBuzz.run() outputs "fizzbuzz".
public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%15==0){
fizzbuzz.acquire();
printFizzBuzz.run();
f(i+1);
}
}
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void number(IntConsumer printNumber) throws InterruptedException {
for(int i=1;i<=n;++i){
if(i%3!=0&&i%5!=0){
number.acquire();
printNumber.accept(i);
f(i+1);
}
}
}
void f(int k){
if(k%3==0&&k%15!=0){
fizz.release();
return ;
}
if(k%5==0&&k%15!=0){
buzz.release();
return ;
}
if(k%15==0){
fizzbuzz.release();
return ;
}
number.release();
}
}
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class DiningPhilosophers {
private Semaphore[] semaphores=new Semaphore[5];
private int n=5;
private volatile int[] a=new int[5];
private Lock lock=new ReentrantLock();
public DiningPhilosophers() {
for(int i=0;i<5;++i){
semaphores[i]=new Semaphore(1);
}
}
// call the run() method of any runnable to execute its code
public void wantsToEat(int philosopher,
Runnable pickLeftFork,
Runnable pickRightFork,
Runnable eat,
Runnable putLeftFork,
Runnable putRightFork) throws InterruptedException {
lock.lock();
try {
semaphores[philosopher].acquire();
pickRightFork.run();
semaphores[(philosopher-1+n)%n].acquire();
pickLeftFork.run();
eat.run();
semaphores[philosopher].release();
putRightFork.run();
semaphores[(philosopher-1+n)%n].release();
putLeftFork.run();
} catch (Exception e) {
//TODO: handle exception
}finally{
lock.unlock();
}
}
}