Java线程/并发性/增量关闭一个错误

Java线程/并发性/增量关闭一个错误,java,multithreading,concurrency,Java,Multithreading,Concurrency,我们一直在提供代码,并要求使其线程安全。从本质上说,这是一个在网络上的变体 消费者/生产者习语。命令行包含3个参数,startValue、min和max。 问题是,当缓冲区达到最小值或最大值时,它的增量计算似乎偏离了1 这可能是显而易见的,但我已经盯着这个太久了,看不到它-任何反馈非常感谢 class Bag { private int sweets, in, out; private final int start,min, max; private boolean

我们一直在提供代码,并要求使其线程安全。从本质上说,这是一个在网络上的变体 消费者/生产者习语。命令行包含3个参数,startValue、min和max。 问题是,当缓冲区达到最小值或最大值时,它的增量计算似乎偏离了1

这可能是显而易见的,但我已经盯着这个太久了,看不到它-任何反馈非常感谢

class Bag {

    private int sweets, in, out;
    private final int start,min, max;
    private boolean full;
    private boolean empty;


    public Bag(int start, int min, int max) {

            this.start = start;
            sweets = start;
            this.min = min;
            this.max = max;
            in = start;
    }



    public synchronized void addSweet() {

        while(full) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets++;
        in++;
        if(sweets==max) full = true;
        empty = false;
        notifyAll();
    }

    public synchronized void removeSweet() {

        while(empty) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets--;
        out++;
        if(sweets==min) empty = true;
        full = false;
        notifyAll();


    }

    public String delta() {
        return("Delta = " + (in-out-sweets) + " Sweets = " + sweets);
    }


}


class Child extends Thread { //consumer

    private Bag bag;
    public Child(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.removeSweet();
        }
    }
}

class Parent extends Thread { //producer

    private Bag bag;

    public Parent(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.addSweet();
        }
    }
}

public class NewSweets {

    static int startValue, min, max = 0;

    public static void main(String[] args) throws InterruptedException {

        if(args.length<2) {
            System.err.println("Usage: java Sweets.java startValue, min, max");
            System.exit(1);
        }



        try {
            startValue = Integer.parseInt(args[0]);
            min = Integer.parseInt(args[1]);
            max = Integer.parseInt(args[2]);
        } catch (NumberFormatException e) {
            System.err.println("Args must be integers.");
            System.exit(1);
        }


        Bag bag = new Bag(startValue, min, max);
        Child cthread = new Child(bag);
        Parent pthread = new Parent(bag);

        pthread.start(); //changed order here
        cthread.start();


        while(true) {

            Thread.sleep(2000);
            System.out.println(bag.delta());
        }
    }
}
类包{
私人糖果,进进出出;
专用最终整数开始,最小值,最大值;
私有布尔满;
私有布尔空;
公共包(整数开始、整数最小值、整数最大值){
this.start=start;
糖果=开始;
this.min=min;
this.max=max;
in=开始;
}
公共同步的void addSweet(){
while(完整){
试一试{
等待();
}捕获(中断异常e){}
}
糖果++;
在++中;
如果(sweets==max)full=true;
空=假;
notifyAll();
}
公共同步的void removeSweet(){
while(空){
试一试{
等待();
}捕获(中断异常e){}
}
糖果--;
out++;
如果(sweets==min)为空=true;
满=假;
notifyAll();
}
公共字符串delta(){
返回(“增量=”+(输入输出糖果)+“糖果=”+糖果);
}
}
类子级扩展线程{//consumer
私人包;
公众儿童(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.removeSweet();
}
}
}
类父级扩展线程{//producer
私人包;
公众家长(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.addSweet();
}
}
}
公共类新闻周刊{
静态int起始值,最小值,最大值=0;
公共静态void main(字符串[]args)引发InterruptedException{

如果(args.length答案是Delta需要同步。根据我的评论,删除了布尔值,现在也可以了。谢谢大家

class Bag {

    private int sweets, in, out;
    private final int start,min, max;

    public Bag(int min, int max, int start) {

            this.min = min;
            this.max = max;
            this.start = start;
            sweets = start;
            in = start;
    }



    public synchronized void addSweet() {

        while(sweets==max) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets++;
        in++;
        notifyAll();
    }

    public synchronized void removeSweet() {

        while(sweets==min) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets--;
        out++;
        notifyAll();


    }

    public synchronized String delta() {
        return("Delta = " + (in-out-sweets) + " Sweets = " + sweets);
    }


}


class Child extends Thread { //consumer

    private Bag bag;
    public Child(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.removeSweet();
        }
    }
}

class Parent extends Thread { //producer

    private Bag bag;

    public Parent(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.addSweet();
        }
    }
}

public class Sweets {

    static int startValue, min, max = 0;

    public static void main(String[] args) throws InterruptedException {

        if(args.length<2) {
            System.err.println("Usage: java Sweets.java min max start");
            System.exit(1);
        }



        try {
            startValue = Integer.parseInt(args[2]);
            min = Integer.parseInt(args[0]);
            max = Integer.parseInt(args[1]);
        } catch (NumberFormatException e) {
            System.err.println("Args must be integers.");
            System.exit(1);
        }


        Bag bag = new Bag(min, max, startValue);
        Child cthread = new Child(bag);
        Parent pthread = new Parent(bag);

        pthread.start(); //changed order here
        cthread.start();


        while(true) {

            Thread.sleep(2000);
            System.out.println(bag.delta());
        }
    }
}
类包{
私人糖果,进进出出;
专用最终整数开始,最小值,最大值;
公共包(最小整数、最大整数、起始整数){
this.min=min;
this.max=max;
this.start=start;
糖果=开始;
in=开始;
}
公共同步的void addSweet(){
while(sweets==最大值){
试一试{
等待();
}捕获(中断异常e){}
}
糖果++;
在++中;
notifyAll();
}
公共同步的void removeSweet(){
while(sweets==min){
试一试{
等待();
}捕获(中断异常e){}
}
糖果--;
out++;
notifyAll();
}
公共同步字符串增量(){
返回(“增量=”+(输入输出糖果)+“糖果=”+糖果);
}
}
类子级扩展线程{//consumer
私人包;
公众儿童(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.removeSweet();
}
}
}
类父级扩展线程{//producer
私人包;
公众家长(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.addSweet();
}
}
}
公共级糖果{
静态int起始值,最小值,最大值=0;
公共静态void main(字符串[]args)引发InterruptedException{

如果(args.length答案是Delta需要同步。根据我的评论,删除了布尔值,现在也可以了。谢谢大家

class Bag {

    private int sweets, in, out;
    private final int start,min, max;

    public Bag(int min, int max, int start) {

            this.min = min;
            this.max = max;
            this.start = start;
            sweets = start;
            in = start;
    }



    public synchronized void addSweet() {

        while(sweets==max) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets++;
        in++;
        notifyAll();
    }

    public synchronized void removeSweet() {

        while(sweets==min) {
            try {
                wait();
            } catch (InterruptedException e) { }
        }
        sweets--;
        out++;
        notifyAll();


    }

    public synchronized String delta() {
        return("Delta = " + (in-out-sweets) + " Sweets = " + sweets);
    }


}


class Child extends Thread { //consumer

    private Bag bag;
    public Child(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.removeSweet();
        }
    }
}

class Parent extends Thread { //producer

    private Bag bag;

    public Parent(Bag bag) {
        this.bag = bag;
    }

    public void run() {

        while(true) {
            bag.addSweet();
        }
    }
}

public class Sweets {

    static int startValue, min, max = 0;

    public static void main(String[] args) throws InterruptedException {

        if(args.length<2) {
            System.err.println("Usage: java Sweets.java min max start");
            System.exit(1);
        }



        try {
            startValue = Integer.parseInt(args[2]);
            min = Integer.parseInt(args[0]);
            max = Integer.parseInt(args[1]);
        } catch (NumberFormatException e) {
            System.err.println("Args must be integers.");
            System.exit(1);
        }


        Bag bag = new Bag(min, max, startValue);
        Child cthread = new Child(bag);
        Parent pthread = new Parent(bag);

        pthread.start(); //changed order here
        cthread.start();


        while(true) {

            Thread.sleep(2000);
            System.out.println(bag.delta());
        }
    }
}
类包{
私人糖果,进进出出;
专用最终整数开始,最小值,最大值;
公共包(最小整数、最大整数、起始整数){
this.min=min;
this.max=max;
this.start=start;
糖果=开始;
in=开始;
}
公共同步的void addSweet(){
while(sweets==最大值){
试一试{
等待();
}捕获(中断异常e){}
}
糖果++;
在++中;
notifyAll();
}
公共同步的void removeSweet(){
while(sweets==min){
试一试{
等待();
}捕获(中断异常e){}
}
糖果--;
out++;
notifyAll();
}
公共同步字符串增量(){
返回(“增量=”+(输入输出糖果)+“糖果=”+糖果);
}
}
类子级扩展线程{//consumer
私人包;
公众儿童(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.removeSweet();
}
}
}
类父级扩展线程{//producer
私人包;
公众家长(包){
这个袋子=袋子;
}
公开募捐{
while(true){
bag.addSweet();
}
}
}
公共级糖果{
静态int起始值,最小值,最大值=0;
公共静态void main(字符串[]args)引发InterruptedException{

if(args.lengthI)将删除
空变量的用法。这是一个可以从
sweets
min
/
max
中发现的事实。它在维护中引入了更多的状态。另外,我认为delta应该是
in-out
(否
-sweets
)它应该等于
sweets
。例如,空包,sweet added,delta应该是1。但是,
1-0-1
是0,这似乎不正确。测试时你用什么命令来调用它?现在工作得很好,没有任何控制布尔值和其他一些更改。我会尽快发布最终的代码(不能很快回答我自己的问题)需要同步来保护数据不受并发访问