多线程编程重要的就是标志位Flag,锁,唤醒
多线程编程注意的两个地方:标志位Flag和while
1.判断
2.干活
3.通知+唤醒
之前synchronized锁释放之后线程疯抢争夺资源
但是被Lock,Condition控制后则可以指定线程运行顺序,按需接力,不用疯抢(如果不用Condition依然疯抢)
三个线程交替打印ABC(五次)
package juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintAbcByOrder {
public static void main(String[] args) {
final PrintAbc printAbc = new PrintAbc();
new Thread(()->{
for (int i = 0; i < 5; i++) {
printAbc.printA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
printAbc.printB();
}
}, "B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
printAbc.printC();
}
},"C").start();
}
}
class PrintAbc{
private ReentrantLock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
private int flag = 1;
public void printA(){
lock.lock();
try {
while (flag != 1){
condition1.await();
}
System.out.println("A");
flag = 2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
while (flag != 2){
condition2.await();
}
System.out.println("B");
flag = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
while (flag != 3){
condition3.await();
}
System.out.println("C");
flag = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
进阶版 题目:有ABC三个线程,要求线程A打印五次,B10次,C15次,然后,再同样的顺序来两轮。。。共来十轮
package juc;
import sun.awt.windows.ThemeReader;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class ShareResource{
private int flag = 1;
private ReentrantLock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
//ctrl+alt+t是try catch
public void print5(int totalLoop){
lock.lock();
try {
//1.判断
while (flag != 1){
condition1.await();
}
//干活
for (int i = 1;i <= 5; i++) {
System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
}
//唤醒+通知
flag = 2;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(int totalLoop){
lock.lock();
try {
//1.判断
while (flag != 2){
condition2.await();
}
//干活
for (int i = 1;i <= 10; i++) {
System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
}
//唤醒+通知
flag = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(int totalLoop){
lock.lock();
try {
//1.判断
while (flag != 3){
condition3.await();
}
//干活
for (int i = 1;i <= 15; i++) {
System.out.println("线程名字:"+Thread.currentThread().getName()+"\t次数:"+i+"\t轮数:"+totalLoop);
}
//唤醒+通知
flag = 1;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class ConditionLockDemo {
public static void main(String[] args) {
ShareResource sr = new ShareResource();
new Thread(()->{
for(int i = 1 ; i<=10 ; i++){
sr.print5(i);
}
},"A").start();
new Thread(()->{
for(int i = 1 ; i<=10 ; i++){
sr.print10(i);
}
},"B").start();
new Thread(()->{
for(int i = 1 ; i<=10 ; i++){
sr.print15(i);
}
},"C").start();
}
}