初次总结,有欠缺的地方还请大佬指正
方法一:synchronized wait notify
//synchronized wait notify
public class alternateOutWay1 {
public static void main(String[] args) {
alternateOutWay1Class cu = new alternateOutWay1Class();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
cu.getOdd();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
cu.getEven();
}
}).start();
}
}
class alternateOutWay1Class {
public synchronized void getOdd() {
for (int i = 0; i <= 100; i += 2) {
System.out.println(Thread.currentThread().getName() + " " + i);
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (i > 100) {
this.notify();
}
}
this.notify();
}
public synchronized void getEven() {
for (int i = 1; i <= 100; i += 2) {
System.out.println(Thread.currentThread().getName() + " " + i);
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();
}
}
方法二:ReentrantLock + Condition
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author chain
*
* ReentrantLock + Condition
*
*/
public class alternateOutWay2 {
public static void main(String[] args) {
alternateOut cu = new alternateOut();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
cu.outputOdd();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 51; i++) {
cu.outputEven();
}
}
}).start();
}
}
class alternateOut {
private static int i = 0;
private static boolean flagB = false;
private ReentrantLock lock = new ReentrantLock();
private Condition con = lock.newCondition();
private Condition con1 = lock.newCondition();
public void outputOdd() {
lock.lock();
try {
if (!flagB) {
con1.await();
}
System.out.println(Thread.currentThread().getName() + " A " + i++);
flagB = false;
con.signal();
if(i > 100) {
con1.signal();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void outputEven() {
lock.lock();
try {
if (flagB) {
con.await();
}
System.out.println(Thread.currentThread().getName() + " B " + i++);
flagB = true;
con1.signal();
//这一步是为了将线程正常结束
if(i > 100) {
con.signal();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
方法三:AtomicInteger + volatile
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
* @author chain
*
* AtomicInteger + volatile
*
* 注意一点:incrementAndGet 和 getAndincrement是不一样的
*/
public class alternateOutWay3 {
private static AtomicInteger cxsNum = new AtomicInteger(0);
private volatile static boolean flag = false;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(;100>cxsNum.get();) {
if(!flag && (cxsNum.get() ==0 || cxsNum.incrementAndGet() % 2 == 0)) {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+cxsNum.get());
flag = true;
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(;100>cxsNum.get();) {
if(flag && cxsNum.incrementAndGet() % 2 != 0) {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+cxsNum.get());
flag = false;
}
}
}
}).start();
}
}