java - Is there a way with concurrency, that a same Object.equals(Object) returns false? -
that's pestered mind 1 of days, looking concrete answer.
(please, bear me, not looking make beautiful code. au contraire, i'm lookng problem code smell)
imagine have stateful object comming class foo
public class foo { public int attribute = 0; // hashcode implemented :p @override public boolean equals(object o) { if (o instanceof foo) { foo = (foo) o; return this.attribute == that.attribute; } return false; } }
and have workers on foo
public class doombringer implements runnable { private final foo foo; public doombringer(foo foo) { this.foo = foo; } @override public void run() { this.foo.attribute++; } }
and 1 prints result of #equals
object passed parameter constructor.
public class selfequalitytestprinter implements runnable { private final foo foo; public selfequalitytestprinter(foo foo) { this.foo = foo; } @override public void run() { system.out.println(foo.equals(foo)); } }
is possible false
printed 1 day if have concurrent threads modifying same foo
instance?
my guess it's possible. don't think equals synchronized unless make so. way avoid testing this == o
@ object#equals(object o)
method, same problem may rise comparing different instances should equal.
yes, possible. variables not synchronized can changed @ moment thread given access variables.
if access foo.attribute
synchronized, , .equals
synchronized when referencing attribute
, not case.
more surprising, if 1 thread changed attribute
, thread read afterwards , old value! last piece can fixed through use of volatile keyword. here's explanation of volatile keyword.
as brian , yshavit have said, problems in not declaring variable volatile include race conditions. here, example, 2 threads calling attribute++
result in attribute
being incremented once. second thread increment use unincremented value attribute
stored in cached memory instead of incremented value written first thread.
Comments
Post a Comment