题目
两个线程,一个负责打印1,3,5.。。。99;
另一个负责打印2,4,6,。。。100;
要交替进行,最后打印出来的次序是1,2,3,4,5,6,。。。99,100
使用java.util.concurrent.locks.ReentrantLock;
分析,这里涉及 两个线程的同步,需要用到signal/await;
可以利用并发工具类ReentrantLock,结合这个锁所产生的Condition对象,每个线程各有一个Condition;
注意点:
(1)先打印奇数;
(2)通过await放弃锁之前,要用另一个线程的Condition对象的signal执行唤醒,以让另一个线程可以获取锁,继续执行逻辑; (这2个线程的执行逻辑都在Lock包裹住的逻辑中的,C/C++程序员会不习惯)
流程图
流程图,拿奇数打印线程为例:
代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
- Created by Jungle on 2019/1/21.
*/
@Controller
public class lockcontroller {
//java线程并发库中的锁相当与(synchronized)
// 主/子线程的核心逻辑都要被此锁包裹住
Lock lock = new ReentrantLock();
//线程并发库中用于线程之间通讯的类相当于wait(),notify()
Condition condOdd = lock.newCondition();
Condition condEven = lock.newCondition();
volatile boolean bPrintOdd = true; //优先打印奇数
@RequestMapping("/lockTest")
public String lockTest(Model model) {
new Thread(new Runnable() {
@Override
public void run() {
threadPrintEven();
}
}).start();
//let sub-thread started first (这个延迟,无所谓,只是表明奇数线程先执行还是后执行都可以保证结果符合预期)
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
threadPrintOdd();
return "index";
}
void threadPrintEven()
{
lock.lock();
System.out.println(“even enter lock”);
try {
for (int i = 2; i <= 100; i += 2) {
if (bPrintOdd) {
condOdd.signal();
System.out.println("even signal then wait");
condEven.await();
}
System.out.println(i);
bPrintOdd = true;
}
}catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
System.out.println("even finished");
}
void threadPrintOdd()
{
lock.lock();
System.out.println("odd enter lock ");
try {
for (int i = 1; i < 100; i += 2) {
if (!bPrintOdd) {
condEven.signal();
System.out.println("odd signal then wait");
condOdd.await();
}
System.out.println(i);
bPrintOdd = false;
}
//唤醒另一个线程,打印最后一个偶数
if (!bPrintOdd) {
condEven.signal();
}
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
System.out.println("odd finished");
}
}
- 关于 :java中的sleep()和wait()的区别 ,参考 [这儿]
https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html