需求:两个线程main和sub,sub线程开始执行10次,然后执行权限交给main线程, * main线程执行100次,然后在将执行权限交给sub...循环执行50次
解决方法一:使用synchronized、wait()、notify解决
/**
* @author yzhang
* @date 2018/4/30 20:50
* @desc 两个线程,子线程每次循环10次,主线程每次循环100次,子线程循环完之后主线程循环,共50次
*/
public class TraditionalSynchronizedDemo {
public static void main(String[] args) {
final Business business = new Business();
//创建一个子线程且先开始执行,不然会造成死锁,这里使用java8的新特性 lamdba表达式
new Thread(() -> {
for (int i = 0; i < 50; i++) {
business.sub(i);
}
}).start();
for (int i = 0; i < 50; i++) {
business.main(i);
}
}
}
class Business {
//初始一个状态为true,让子线程开始执行
private Boolean flag = Boolean.TRUE;
public synchronized void sub(int i) {
//判断子线程是否可以执行,不能执行就等待
while (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//执行主体
for (int j = 0; j < 10; j++) {
System.out.println("sub of " + j + ",loop of" + i);
}
//将标志变为false,唤醒main线程继续执行
flag = Boolean.FALSE;
this.notify();
}
public synchronized void main(int i) {
//判断主线程是否可以执行,不能执行就等待
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//执行主体
for (int j = 0; j < 100; j++) {
System.out.println("main of " + j + ",loop of" + i);
}
//将标志变为true,唤醒sub线程继续执行
flag = Boolean.TRUE;
this.notify();
}
}
解决方法二:使用阻塞队列来完成,ArrayBlockingQueue
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author yzhang
* @date 2018/5/26 11:36
* @desc 阻塞队列通信
* 功能:两个线程main和sub,sub线程开始执行10次,然后执行权限交给main线程,
* main线程执行100次,然后在将执行权限交给sub...循环执行50次
*/
public class BlockingQueueCommunication {
public static void main(String[] args) {
final Business business = new BlockingQueueCommunication.Business();
//开启一个子线程,这里使用java8的新特性 lamdba表达式
new Thread(() ->{
for (int i = 0; i < 50; i++) {
business.main(i);
}
}).start();
new Thread(() ->{
for (int i = 0; i < 50; i++) {
business.sub(i);
}
}).start();
System.out.println("主线程当前已经执行完");
}
static class Business {
//先创建两个阻塞队列mainQueue和subQueue,里面的一个空间大小
final BlockingQueue<Integer> subQueue = new ArrayBlockingQueue<Integer>(1);
final BlockingQueue<Integer> mainQueue = new ArrayBlockingQueue<Integer>(1);
{
//初始化的时候,让mainQueue队列满了,这样main方法一开始执行的时候就会在等待状态
try {
mainQueue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* sub方法
*
* @param i 执行i的轮数
*/
public void sub(int i) {
//1.sub队列先去放一个元素,如果能放进去,那么就可以执行,否则等待空闲空间
try {
subQueue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//2.执行操作
for (int j = 0; j < 10; j++) {
System.out.println("sub of " + j + ",loop of" + i);
}
//3.执行完之后应该移除main队列的一个元素,以便于main队列可以继续添加
try {
mainQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* main方法
* @param i 执行的轮数
*/
public void main(int i) {
//4.main队列先去放一个元素,如果能放进去,那么就可以执行,否则等待空闲空间
try {
mainQueue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//5.执行操作
for (int j = 0; j < 100; j++) {
System.out.println("main of " + j + ",loop of" + i);
}
//6.main线程执行完之后,让sub线程执行
try {
subQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
欢迎关注微信公众号“
干货集市
”,我所学知识都是这里面的免费视频资源学到的,里面有大量的多线程高并发视频资源,更多详情请关注微信公众号“
干货集市
”。