简体   繁体   中英

How to change an instance variable of all instances of a class at once, Java

I want to have multiple instances of a class, but be able to change all non-static instances of a variable at once. Maybe this code will be more clear:

public class Example {
     public int _x; //_x and _y are NOT static
     public int _y;
     Example (int x, int y) {
     _x = x;
     _y = y;
     }
     public void zeroThem() {
     _x = 0;
     _y = 0;
     }
}

The point of the zeroThem() method is that I might have

Example A = new Example(1, 2);
Example B = new Example(3, 4);

But once I call something like: A.zeroThem(); The following will be true:

A._x == 0;
B._x == 0;
A._y == 0;
B._y == 0;

Is there any way to do this without making _x and _y static?

This can be achieved with the help of the following fixes:

  1. Your instance variables need to be volatile
  2. You need to have static synchronized collection of Example instances and iterate it.
  3. According to your request, you need to have method zeroAll calling instance method zeroThem . zeroAll may be implemented as non-static, but as soon as it affects all instances of Example it's better to mark it as static .
public class Example {

    private static List<Example> all = Collections.synchronizedList(
        new ArrayList<>());

    public volatile int _x; //_x and _y are NOT static
    public volatile int _y;

    Example (int x, int y) {
        this._x = x;
        this._y = y;
        Example.all.add(this);
    }

    public void zeroThem() {
        _x = 0;
        _y = 0;
    }

    public static void zeroAll() {
        synchronized(Example.all) {
            Example.all.forEach(Example::zeroThem);
        }
    }
}

Update Addressing comment to resolve memory leak issue using WeakReference and ReferenceQueue :

import java.lang.ref.*;
import java.util.*;

public class Example {

    private static final ReferenceQueue<Example> refQueue = new ReferenceQueue<>();
    private static final List<WeakReference<Example>> all = Collections.synchronizedList(new ArrayList<>());

    public volatile int _x; //_x and _y are NOT static
    public volatile int _y;

    Example (int x, int y) {
        this._x = x;
        this._y = y;
        Example.all.add(new WeakReference<>(this, refQueue));
    }

    public void zeroThem() {
        _x = 0;
        _y = 0;
    }

    public static void zeroAll() {
        synchronized(Example.all) {
            Example.all.removeIf(ref -> ref.get() == null); // delete non-existing instances
            Example.all
                .stream()
                .map(WeakReference::get)
                .forEach(Example::zeroThem);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM