栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java 多线程&wait条件发生变化与使用while的必要性——77

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java 多线程&wait条件发生变化与使用while的必要性——77

        在使用wait/notify模式时,还需要注意一种情况,即wait 条件发生变化,容易造成逻辑的混乱。
创建类Add.java
package chapter3.test3_1.test3_1_18;


public class Add {
    private String lock;

    public Add(String lock) {
        super();
        this.lock = lock;
    }

    public void add() {
        synchronized (lock) {
            ValueObject.list.add("anyString");
            lock.notifyAll();
        }
    }
}
 创建类Subtract.java
package chapter3.test3_1.test3_1_18;

public class Subtract {
    private String lock;

    public Subtract(String lock) {
        super();
        this.lock = lock;
    }

    public void subtract() {
        try {
            synchronized (lock) {
                if (ValueObject.list.size() == 0) {
                    System.out.println("wait begin ThreadName=" + Thread.currentThread().getName());
                    lock.wait();
                    System.out.println("wait end ThreadName=" + Thread.currentThread().getName());
                }
                ValueObject.list.remove(0);
                System.out.println("list size=" + ValueObject.list.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
类ValueObject.java代码
package chapter3.test3_1.test3_1_18;

import java.util.ArrayList;
import java.util.List;

public class ValueObject {
    public static List list = new ArrayList();
}
两个线程类代码
package chapter3.test3_1.test3_1_18;

public class ThreadAdd extends Thread {
    private Add p;

    public ThreadAdd(Add p) {
        super();
        this.p = p;
    }

    @Override
    public void run() {
        p.add();
    }
}
package chapter3.test3_1.test3_1_18;

public class ThreadSubtract extends Thread {
    private Subtract r;

    public ThreadSubtract(Subtract r) {
        super();
        this.r = r;
    }

    @Override
    public void run() {
        r.subtract();
    }
}
类Run.java代码
package chapter3.test3_1.test3_1_18;

public class Run {
    public static void main(String[] args) throws InterruptedException {
        String lock = new String("");
        Add add = new Add(lock);
        Subtract subtract = new Subtract(lock);

        ThreadSubtract subtract1Thread = new ThreadSubtract(subtract);
        subtract1Thread.setName("subtract1Thread");
        subtract1Thread.start();

        ThreadSubtract subtract2Thread = new ThreadSubtract(subtract);
        subtract2Thread.setName("subtract2Thread");
        subtract2Thread.start();

        Thread.sleep(1000);
        ThreadAdd addThread = new ThreadAdd(add);
        addThread.setName("addThread");
        addThread.start();
    }
}
程序运行结果

出现异常的原因 
        出现异常的原因是有两个实现删除remove()操作的线程,它们在 “Thread.sleep ( 1000 ); ” 之前都执行了wait()方法,呈等待状态,当加操作的线程在1s之后被运行时,通知了所有呈等待状态的减操作线程,那么第一个实现减操作的线程能正确地删除 list 中索引为 0的数据,但第二个实现减操作的线程则出现索引溢出的异常,因为list中仅仅添加了一个数据,也只能删除一个数据,没有第二个数据可供删除,所以出现了java.lang.Index-OutOfBoundsException 异常。
如何解决这种情况呢?更改Subtract.java中的subtract方法代码

 

package chapter3.test3_1.test3_1_18.test1;

public class Subtract {
    private String lock;

    public Subtract(String lock) {
        super();
        this.lock = lock;
    }

    public void subtract() {
        try {
            synchronized (lock) {
                while (ValueObject.list.size() == 0) {
                    System.out.println("wait begin ThreadName=" + Thread.currentThread().getName());
                    lock.wait();
                    System.out.println("wait end ThreadName=" + Thread.currentThread().getName());
                }
                ValueObject.list.remove(0);
                System.out.println("list size=" + ValueObject.list.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
程序运行结果

不再出现异常 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/995727.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号