static and threads

J

John C. Bollinger

Oliver said:
Okay, here's the next situation I've concocted where I can't figure out
how to implement it without using statics. Let's say you have some sort of
hardware hooked up to your computer (e.g. a webcam, atom decay-sensor,
joystick, etc.) and you want a class to act as an abstraction of that
hardware. Since you only have one copy of that hardware, you'd like to
ensure only one instance of that class binds to the hardware (assume
something disastrous happens if two instances tries to bind to the same
hardware). Can you design a robust class library for this without using
statics?

The underlying question being what would I use instead of the
much-overused Singleton pattern? I pretty much universally prefer the
"Just Use One" strategy over the Singleton pattern, even without
consideration of implementation details such as static members. There
are a number of ways to "Just Use One", but they all boil down to
passing around a reference to some object from which you can obtain a
reference to the designated instance. In some cases you might be able
to use inner/containing class relationships instead of passing around
explicit references.

You will no doubt observe that so far I have sidestepped the main thrust
of your question. In part this is because I see it as based on a
largely artificial requirement (to *ensure* that only one instance binds
to the hardware). It is often entirely sufficient to simply say "don't
do that". That's especially so when you can't programmatically *ensure*
compliance, which is the case here. Static class members avail nothing
if a different copy of the class is loaded via a different classloader
or in a different VM. Or if other code, possibly in an unrelated piece
of software, interacts with the hardware independently of the
hypothetical Java class library.

With that said, the Factory pattern is the usual fall back for all
questions of controlling and/or monitoring the creation of objects. Its
specific application to the problem you raise might take the form of a
factory implementation that maintains an internal map from hardware
identifiers to interface objects, and uses it to always provide the same
interface object in response to all requests for interfaces to the same
hardware.
 
J

John C. Bollinger

Chris said:
John C. Bollinger wrote:




Without using static fields /anywhere/ ??
Yes.

The only ways that I can think of
would either involve passing a reference to the factory as a parameter to every
method call in every calling chain from main() to the point where the factory
was used, or doing something similar to ensure that all objects (that needed
them) would have a reference to the factory held in their instance state.

Not what /I/ would call "eminently possible" ;-)

In full generality, yes, it would be a burden, but it could be done.
Please recall that I have not claimed that static members should be
avoided at all costs, without exception. In point of fact, however, I
do think the particular requirement under discussion at the moment is a
bit contrived.
(Not a serious point, John, I'm just being pedantic...)

Duly noted.

At the risk of going slightly OT, is it not the case that there are OO
languages that have no equivalent of Java's static members?
 
C

Chris Uppal

John said:
At the risk of going slightly OT...

In the certain knowledge that /I/'m going OT :)...

....is it not the case that there are OO
languages that have no equivalent of Java's static members?

The only fully OO language that I know well enough to pontificate about is
Smalltalk[*]. In that language classes are full objects, and -- as such --
they maintain their own state in their own instvars ("instance fields" in Java
terms) like any other object. Thus they can act naturally as both factory
objects, and as the "owners" of any state that is used by their instances (you
don't /have/ to arrange things like that, of course, and sometimes it is
appropriate to create one or more separate objects to handle those
responsibilities -- but that gives you no /semantic/ advantage, since it's just
a question of /which/ object does X rather than /whether/ an object does X, as
usual balancing the risks of over-engineering against the risks of
inappropriately factored responsibility).

In Smalltalk no object has access to /any/ other object's instvars (though
objects can "see" instvars inherited from superclasses[**]). As a result of
that:
a) no object can "see" its class's instvars
b) no class object can "see" its instances' instvars
c) no class can see its superclass's or subclasses' instvars.

Unfortunately, Smalltalk /does/ have an additional (and very hacky) concept of
variables that can be associated with class objects in such a way that they can
be "seen" by the class (or even by several otherwise unrelated classes), its
subclasses, and all their instances. These things are subject to all the kinds
of misuse that are possible with Java's static fields. In general the ST
community frowns upon their use (I scowl very deeply indeed at any use except
to hold "compile time"[***] constants -- some pundits discourage even that).

-- chris

[*] Ruby follows the Smalltalk pattern in general, but I don't really know Ruby
well enough to be sure that there aren't important exceptions in this area.

[*] Which makes sense if you are thinking in object-centric terms as opposed
to code-centric terms (the later being the mindset that, IMO, is most typical
amongst Java and C++ programmers.

[**] The scare quotes around "compile time" are because Smalltalk doesn't have
a separation between compile-time and runtime -- still, the term conveys the
general idea of values that remain constant for the lifetime of the code.
 
R

Roedy Green

In that language classes are full objects

In Java this is feels somewhat squishy. Classes are sort of like
objects. You have the static fields which are a bit like instance
variables of a class object. You also have the twin .class object that
owns methods like getresource. You don't have any direct way to
instantiate a class or modify its methods.
 
R

Roedy Green

Perhaps an alternative way of phrasing that would appeal: static fields require
as much care as any other field, but they don't always get it.

Statics are more likely to get in trouble. Threads naturally tend to
mess with one object, and a different one from other threads. Where
statics are very likely to be in contention.

This might be a time to remind people of the possibility of using
static lock objects new Object() to lock out SOME static fields rather
than locking on the whole class at a time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top