java多線程 六脈神劍
- BlockingQueue
- 信號量Semaphore
- synchronized + 標(biāo)志位 + 喚醒
- ReentrantLock + Condition
- 自旋yield()讓出CPU
- CyclicBarrier控制先后 或使用CountDownLatch+CyclicBarrier
解決下列問題
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實(shí)例 其中一個線程調(diào)用foo() 另一個線程調(diào)用bar()
設(shè)計修改程序配紫,保證“foobar”被輸出n次
示例: 輸入n=2 輸出 “foobarfoobar”
1.利用BlockingQueue
class Foobar{
private int n;
private BlockingQueue<Integer> bar = new LinkedBlockingQueue<>(1);
private BlockingQueue<Integer> foo = new LinkedBlockingQueue<>(1);
public FooBar(int n){
this.n= n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
foo.put(i);
printFoo.run();
bar.put(i);
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
bar.take();
printBar.run();
foo.take();
}
}
}
2.利用Semaphore
class FooBar{
private int n;
private Semaphore foo = new Semaphore(1);
private Semaphore bar = new Semaphore(0);
public FooBar(int n){
this.n= n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
foo.acquire();
printFoo.run();
bar.release();
}
}
public void bar(Runnable printBar)throws InterruptedExceptions{
for(int i=0;i<n;i++){
bar.acquire();
printBar.run();
foo.release();
}
}
}
3.利用synchronized + 標(biāo)志位 + 喚醒
class FooBar{
private int n;
private volatile boolean type = true;
private Object foo = new Object();
public FooBar(int n){
this.n=n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
synchronized(foo){
while(!type){
foo.wait();
}
printFoo.run();
type = false;
foo.notifyAll();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
synchronized(foo){
while(type){
foo.wait();
}
printBar.run();
type= true;
foo.notifyAll();
}
}
}
}
4.利用可重入鎖ReentrantLock+Condition
class FooBar{
private int n;
private Lock lock = new ReentrantLock(true);
private final Condition foo = lock.newCondition();
private volatile boolean flag = true;
public FooBar(int n){
this.n = n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;i++){
lock.lock();
try{
while(!flag){
foo.await();
}
printFoo.run();
flag=false;
foo.signal();
}finally{
lock.unlock();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
lock.lock();
try{
while(flag){
foo.await();
}
printBar.run();
flag= true;
foo.signal();
}finally{
lock.unlock();
}
}
}
}
5.利用自旋讓出CPU
class FooBar{
private int n;
private volatile boolean flag = true;
public FooBar(int n){
this.n=n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i=0;i<n;){
if(flag){
printFoo.run();
i++;
flag= false;
}else{
Thread.yield();
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;){
if(!flag){
printBar.run();
i++;
flag = true;
}else{
Thread.yield();
}
}
}
}
6.利用CyclicBarrier控制先后
class FooBar{
private int n;
volatile boolean flag = true;
CyclicBarrier cb = new CyclicBarrier(2);
public FooBar(int n){
this.n=n;
}
public void foo(Runnable printFoo)throws InterruptedException{
for(int i = 0;i<n;i++){
while(!flag);
printFoo.run();
flag=false;
try{
cb.await();
}catach(Exception e){
}
}
}
public void bar(Runnable printBar)throws InterruptedException{
for(int i=0;i<n;i++){
try{
cb.await();
}catch(Exception e){
}
printBar.run();
flag=true;
}
}
}
利用CountDownLatch保證任務(wù)執(zhí)行的先后順序洲愤,CyclicBarrier保證任務(wù)按組進(jìn)行
class FooBar{
private int n;
private CountDownLatch a;
private CyclicBarrier barrier;
public FooBar(int n){
this.n=n;
a = new CountDownLatch(1);
barrier= new CyclicBarrier(2);
}
public void foo(Runnable printFoo)throws InterruptedException{
try{
for(int i=0;i<n;i++){
printFoo.run();
a.countDown();
barrier.await();
}
}catch(Exception e){
}
}
public void bar(Runnable printBar)throws InterruptedException{
try{
for(int i=0;i<n;i++){
a.await();
printBar.run();
a = new CountDownLatch(1);
barrier.await();
}
}catch(Exception e){
}
}
}