java - 我应该使用原子整数还是同步

标签 java multithreading concurrency synchronization atomic

我对在代码中使用原子/ volatile /同步有点困惑。 假设我在书店中有一个图书信息对象,例如,可能会发生两个线程想要拿同一本书,而库存数量只有1,我如何保证只有一个线程会拿这本书? 我必须使用同步吗? 图书库存信息:

package bgu.spl.mics.application.passiveObjects;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Passive data-object representing a information about a certain book in the inventory.
 * 
 * <p>
 *
 */
public class BookInventoryInfo {

    //The title of the book, his amount in the inventory and the price
    private String bookTitle;
    private AtomicInteger amountInInventory;
    private int price;

    public BookInventoryInfo(String bookTitle, int amountInInventory, int price) {
        this.bookTitle = bookTitle;
        this.price = price;
        this.amountInInventory = new AtomicInteger(amountInInventory);
    }


    /**
     * Retrieves the title of this book.
     * <p>
     * @return The title of this book.   
     */
    public String getBookTitle() {
        return this.bookTitle;
    }

    /**
     * Retrieves the amount of books of this type in the inventory.
     * <p>
     * @return amount of available books.      
     */
    public int getAmountInInventory() {
        return this.amountInInventory.get();
    }

    /**
     * Retrieves the price for  book.
     * <p>
     * @return the price of the book.
     */
    public int getPrice() {
        return this.price;
    }

    public void reduceAmountInInventory() {
        this.amountInInventory.decrementAndGet();
    }
}

我想如何看待这本书:

if(book.getAmountInInventory > 0)
{
    book.amountInInventory--
}

最佳答案

您应该使用synchronized,因为使用 AtomicInteger 并不像乍一看那么简单。虽然 AtomicInteger 上的单个操作是线程安全的,但使用多个操作可能不是。你的例子就是一个很好的例子。说你有

// say it start at 1
Thread1: if(book.getAmountInInventory > 0)
Thread2: if(book.getAmountInInventory > 0)
Thread1: book.amountInInventory--
Thread2: book.amountInInventory--

金额现在为-1。

如果您使用synchronized,则为整个操作持有锁会简单得多

synchronized (book) {
    if(book.getAmountInInventory > 0) // no chance for a race condition here.
    {
        book.amountInInventory--
    }

关于java - 我应该使用原子整数还是同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53776188/

相关文章:

java - Spring Boot ,gradle,angularJS和一个 fat jar

java - ImageJ API : Usage of Filter in my own Code

multithreading - 如何更好地解释 “deadlock”?

java - 并发修改异常

ASP.NET 后台工作线程

java - 如何将测试库(例如 JUnit)添加到 Intellij "Create Test Class"对话框

java - 单元测试中的@Autowire 似乎不起作用

python - 如何在 Python 3 中引用线程?

java - Java中main()方法和主线程有什么关系?

java - 连续线程执行