交替打印奇偶数(前100个)
设置初值start
对flag的写入虽然加锁保证了线程安全,但是读取的时候,由于不是volatile类型可能会读到旧值
使用重入锁ReentrantLock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 两个线程交替执行打印1~100
* @author yinlu
* @since JDK 1.8
*/
public class TwoThread {
private int start = 1;
private volatile boolean flag = false;
private final static Lock lock = new ReentrantLock();
public static void main(String[] args) {
TwoThread twoThread = new TwoThread();
Thread t1 = new Thread(new OuNum(twoThread));
t1.setName("t1");
Thread t2 = new Thread(new JiNum(twoThread));
t2.setName("t2");
t1.start();
t2.start();
}
/**
* 偶数线程
*/
public static class OuNum implements Runnable{
private TwoThread number;
public OuNum(TwoThread number){
this.number = number;
}
@Override
public void run(){
while (number.start <= 100){
if(number.flag){
try{
lock.lock();
System.out.println(Thread.currentThread().getName() + " : " + number.start);
number.start++;
number.flag = false;
}finally {
lock.unlock();
}
}
}
}
}
public static class JiNum implements Runnable{
private TwoThread number;
public JiNum(TwoThread number){
this.number = number;
}
@Override
public void run(){
while (number.start <= 100){
if(!number.flag){
try{
lock.lock();
System.out.println(Thread.currentThread().getName() + " : " + number.start);
number.start++;
number.flag = true;
}finally {
lock.unlock();
}
}
}
}
}
}
运行结果
实现生产者/消费者模式:一对一交替打印
使用ReentrantLock和Condition对象里的wait()方法和signal()方法
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 交替打印 生产者/消费者
* @author yinlu
* @since JDK 1.8
*/
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasvalue = false;
public void set() {
try {
lock.lock();
while (hasvalue == true) {
condition.await();
}
System.out.println("生产者");
hasvalue = true;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasvalue == false) {
condition.await();
}
System.out.println("消费者");
hasvalue = false;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
MyService myService = new MyService();
MyThreadA a = new MyThreadA(myService);
a.start();
MyThreadB b = new MyThreadB(myService);
b.start();
}
public static class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
myService.set();
}
}
}
public static class MyThreadB extends Thread {
private MyService myService;
public MyThreadB (MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
myService.get();
}
}
}
}