多线程案例分析一
设计4个线程对象,两个线程执行减操作,两个线程执行加操作。
package cn.mldn.demo;
public class ThreadDemo {
public static void main(String[] args) {
Resource res = new Resource();
AddThread at = new AddThread(res);
SubThread st = new SubThread(res);
new Thread(at, "加法线程 - A").start();
new Thread(at, "加法线程 - B").start();
new Thread(st, "减法线程 - X").start();
new Thread(st, "减法线程 - Y").start();
}
}
class Resource { // 定义一个操作的资源
private volatile int num = 0; // 这个要进行加减操作的数据
private boolean flag = true; // 加减的切换
//flag = true,表示可以允许加法操作,但是无法进行减法操作
//flag = flase,表示可以允许减法操作,但是无法进行加法操作
public synchronized void add() throws InterruptedException { // 执行加法操作
if (this.flag == false) { // 现在需要执行的是减法操作,加法操作要等待
super.wait();
}
Thread.sleep(100);
this.num++;
System.out.println("【加法操作-" + Thread.currentThread().getName() + "】" + "num=" + this.num);
this.flag = false; // 加法操作执行完毕,需要执行减法处理
super.notifyAll(); // 唤醒全部等待线程
}
public synchronized void sub() throws InterruptedException { // 执行减法操作
if (this.flag == true) { // 减法操作需要等待
super.wait();
}
Thread.sleep(200);
this.num--;
System.out.println("【减法操作-" + Thread.currentThread().getName() + "】" + "num=" + this.num);
this.flag = true; // 执行完减法,将允许加法不允许减法
super.notifyAll(); // 唤醒所有等待线程
}
}
class AddThread implements Runnable {
private Resource resource;
public AddThread(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int x = 0; x < 50 ; x++) {
try {
this.resource.add();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SubThread implements Runnable {
private Resource resource;
public SubThread(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int x = 0; x < 50 ; x++) {
try {
this.resource.sub();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这一题目是一个经典的多线程的开发操作,这一个程序里面一定要考虑的核心本质在于:加一个、减一个,整体的计算结果应该只在0、-1、1之间循环出现。