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:
volatile
Example
instances and iterate it.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.