Путаница в отношении потоков и безопасности потоков - PullRequest
0 голосов
/ 09 января 2020

Чтобы лучше понять концепцию потоков, мы должны использовать объект Number, который можно увеличивать, уменьшать, возводить в квадрат и внедрять с помощью его методов. Единственный атрибут - это двойное число (инициализируется как число = 1).

Так что, если я создаю экземпляр объекта Number и вызываю increment (), decment (), square () и root () 100000000 раз, чтобы этот числовой объект, числовой атрибут снова равен 1 (как и ожидалось).

Теперь проблема в том, что мы должны создать два объекта потока, один из которых вызывает увеличение / уменьшение в 100000000 раз, а другой вызывает квадрат / root 100000000 раз. Согласно нашему учителю, результатом было бы несоответствие, т.е. в результате я получаю 0 вместо 1, но в моей программе это просто дает мне бесконечность или 1, в зависимости от того, используется ли функция synchronized () в классе Thread или нет.

public class Calculation {

    public static void main(String[] args) throws InterruptedException {
        Number num = new Number();
        Number num1 = new Number();

        for (int i = 0; i < 100000000; i++) {
            num.increment();
        }

        for (int i = 0; i < 100000000; i++) {
            num.decrement();
        }

        for (int i = 0; i < 100000000; i++) {
            num.square();
        }

        for (int i = 0; i < 100000000; i++) {
            num.root();
        }
        System.out.println(num.getNumber());
        CalcThread t1 = new CalcThread(num1, true);
        CalcThread t2 = new CalcThread(num1, false);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(num1.getNumber());   
    }
}
public class CalcThread extends Thread {
    public Number num;
    public boolean decision;

    public CalcThread(Number num, boolean decision) {
        this.num = num;
        this.decision = decision;
    }

    @Override
    public void run() {
        synchronized(num) {
        if (this.decision) {
            for (int i = 0; i < 100000000; i++) {
                num.square();
            }
            for (int i = 0; i < 100000000; i++) {
                num.root();
            }
        } else {
            for (int i = 0; i < 100000000; i++) {
                num.increment();
            }
            for (int i = 0; i < 100000000; i++) {
                num.decrement();
            }
        }
        }
    }
}

public class Number {
    double number;
    public Number() {
        this.number = 1;    
    }

    public void increment() {
        this.number++;
    }

    public void decrement() {
        this.number--;
    }

    public void square() {
        this.number = this.number * this.number;
    }

    public void root() {
        this.number = Math.sqrt(this.number);
    }

    public double getNumber() {
        return number;
    }

    public void setNumber(double number) {
        this.number = number;
    }
}

Получение бесконечности при выходе из синхронизации имеет смысл, поскольку оно увеличивается при одновременном возведении в квадрат числа, поэтому число скоро станет слишком большим, чтобы соответствовать размеру двойного шрифта правильно? Как получить несоответствие, о котором говорил мой учитель?

Заранее благодарю за помощь.

...