Java share a variable between two threads

后端 未结 4 1992
慢半拍i
慢半拍i 2020-12-11 01:06

I have two threads. One invokes the update method of a class that modifies a variable. Another invokes the update method of a class that reads the variable. Only one thread

相关标签:
4条回答
  • 2020-12-11 01:16

    Not only should variable be volatile, but you also want to protect your update function with some sort of synchronization since ++variable is not an atomic call. It is, after all, just syntactic sugar for

    variable = variable + 1;
    

    which is not atomic.

    You should also wrap any calls that read variable in a lock of some sort.

    Alternatively, use an AtomicInteger. It was made for this sort of thing (for just integer operations).

    public class A
    {
        // initially had said volatile wouldn't affect this variable because
        // it is not a primitive, but see correction in comments
        public final AtomicInteger variable; // see comments on this issue of why final
        public void update()
        {
            // Called by one thread constantly
            variable.getAndIncrement(); // atomically adds one
        }
        public int retrieveValue()
        {
            return variable.get(); // gets the current int value safely
        }
    }
    
    public class B
    {
        public A a;
        public void update()
        {
            // Called by another thread constantly
            int v = a.retrieveValue();
            // Do algorithm with v...
        }
    }
    

    For the more complex algorithms, as your recent edit assumes, use synchronization or locks.

    0 讨论(0)
  • 2020-12-11 01:31

    If there is one and only one thread that writes to variable you can get away with making it volatile. Otherwise see the answer with AtomicInteger.

    Only volatile will work in case of only one writing thread because there is only one writing thread so it always has the right value of variable.

    0 讨论(0)
  • 2020-12-11 01:35

    In this case I would use an AtomicInteger, however the generalised answer is that access to variable should be protected by a synchronized block, or by using another part of the java.util.concurrent package.

    A couple of examples:

    Using synchronized

    public class A {
        public final Object variable;
        public void update() {
            synchronized(variable) {
                variable.complexAlgorithm();
            }
        }
    }
    
    public class B {
        public A a;
        public void update() {
            sychronized(a.variable) {
                consume(a.variable);
            }
        }
    }
    

    Using java.util.concurrent

    public class A {
        public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        public final Object variable;
        public void update() {
            lock.writeLock().lock();
            try {
                variable.complexAlgorithm();
            } finally {
                lock.writeLock().unlock();
            }
        }
    }
    
    public class B {
        public A a;
        public void update() {
            a.lock.readLock().lock();
            try {
                consume(a.variable);
            } finally {
                a.lock.readLock().unlock();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-11 01:38

    Use AtomicInteger or synchronize the access to be safe.

    0 讨论(0)
提交回复
热议问题