Java之多线程的数字加减案例(同步,等待与唤醒)

多线程控制数字的加减:

线程控制数字的加减过程应该是一个加一个减,这个和消费者模型有点像,加了后再减,加减不同同时进行,所以存在同步的问题。

/* 定义一个操作资源
*   这个类用来创建数值和加减切换开关还有加减的操作
*   其它线程类则创建这个类的属性来进行关联,并调用这个类中的方法实现加减的操作。
* */
public class Resource {
    private int num = 0;    // 进行加减操作的数据
    private boolean flag =true; // 加减的切换
    // flag = true : 表示可以进行加法操作,不能减法操作
    // flag = false : 表示可以进行减法操作,不能加法操作
    public synchronized void add(){ // 加法操作,已同步
        if (this.flag == false){    // 现在需要执行的是减法操作,加法操作需要等待
            try {
                super.wait();   // super 表示父类,wait()是Object的方法所以super指向的是Object
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //延迟
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.num ++;
        System.out.println("【加法操作】- " + Thread.currentThread().getName() + ": num = " + this.num);
        // 因为flag = true执行加法,所以将flag设置为false执行减法
        this.flag = false;      // 加法操作执行完毕,需要进行减法操作
        // super 表示父类,notifyAll()是Object的方法所以super指向的是Object
        super.notifyAll();      // 等待的可能是加法或者减法,那么就唤醒全部线程
    }
    public synchronized void sub(){ // 减法操作,已同步
        if (this.flag == true){    // 现在需要执行的是加法操作,减法操作需要等待
            try {
                super.wait();   // super 表示父类,wait()是Object的方法所以super指向的是Object
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //延迟
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.num --;
        System.out.println("【减法操作】- " + Thread.currentThread().getName() + ": num = " + this.num);
        this.flag = true;   // true:执行加法
        super.notifyAll();      // super 表示父类,notifyAll()是Object的方法所以super指向的是Object
    }

}

 

// 加法线程
public class AddThread implements Runnable{
    private Resource resource;
    public AddThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            this.resource.add();
        }
    }
}

 

// 减法线程
public class SubThread implements Runnable{
    private Resource resource;
    public SubThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            this.resource.sub();
        }
    }
}

 

// 客户端
public class Main {
    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,"减法线程 - A").start();
        new Thread(st,"减法线程 - B").start();
    }
}

输出结果:

Java之多线程的数字加减案例(同步,等待与唤醒)

 

num的值最终为0,加减法的交替进行得以验证,但是因为线程优先级的问题,无法保证某一个方法的某个线程先执行。

 

上一篇:Ambari2.7.4集成Kylin3.0


下一篇:面向对象day03