Using ReentrantLock

M

markspace

RVince said:
There's a level of
abstraction here that I am just not seeing, and I don;t know why


That's obviously true and very big of you to admit. I think Arved's
idea to go read the Java tutorial on concurrency was very good. There
maybe some other articles on Java concurrency that you may be able to
gain some insight from. I'm not willing explain the whole thing to you
myself. It's a large subject and an explanation would be a lot of
effort on my part. I'd be happy to answer questions about the tutorial
though, that's much less effort on my part.

To try to clear up what is going on here, this is more what I was
thinking of:


public class SynchedOutputStream extends OutputStream {

private OutputStream out;
private ReentrantLock lock = new ReentrantLock();

public SynchedOutputStream( OutputStream out )
{
this.out = out;
}

@Override
public void write( int c ) throws IOException
{
try {
lock.lock();
out.write( c );
}
finally {
lock.unlock();
}
}

@Override
public void write( byte [] buf, int offset, int len )
throws IOException
{
try {
lock.lock();
out.write( buf, offset, len );
}
finally {
lock.unlock();
}
}
}

Notice that: the lock is private, and never made public to anyone. And
the object is fully self contained -- I use no global or static objects
to do the work. I wrap an output stream, and that's it. The output
stream could be public -- depends what the caller does with it. But
that's up to the caller, not me.

Hopefully this clears things up a bit. Note also this code was syntax
checked (which we asked you for, work or not you can still compile a
short code example), although I admit I didn't run an tests on it.

I understand that this code does not group several writes together, but
I think that's easily overcome. Just group your writes into a single
buffer (like StringBuilder) and then write the result in one go.

Also note that if you are doing logging, or tasks that require large
through put, this is a terrible idea, because your going to block all
your threads on a single IO object. Just saying.
 
L

Lew

Pitch said:
What would you use?

A name whose every part contributes to understanding of the variable's role.
Since every reference points to an object in Java, the 'Object' part of the
name does not do that; it is redundant. It is as unnecessary as calling a
class "FooClass" or an interface "FooInterface" (a practice that is not only
redundant but reduces the usefulness of the names), a method "FooMethod()" or
a member "mFoo". Names should reflect the purpose of a variable, not its
implementation.
 
P

Pitch

A name whose every part contributes to understanding of the variable's role.
Since every reference points to an object in Java, the 'Object' part of the
name does not do that; it is redundant. It is as unnecessary as calling a
class "FooClass" or an interface "FooInterface" (a practice that is not only
redundant but reduces the usefulness of the names), a method "FooMethod()" or
a member "mFoo". Names should reflect the purpose of a variable, not its
implementation.


You didn't answer my question. :)


I agree mostly with what you say but maybe there should be exceptions:

- IConfig vs Config: In Java we don't use "I" which makes very difficult
to distiguish a class from an interface.

- Absence of "m" or "m_" forces us to uses "this.foo = foo" when we have
arguments of the same name. (Even though I mostly dislike C-like
naming).

- Even Java does not conform to this purpose-implementation rule; you
have "Abstract" for abstract classses.
 
L

Lew

You didn't answer my question. :)

Yes, I did. I said, "A name whose every part contributes to
understanding of the variable's role."
I agree mostly with what you say but maybe there should be exceptions:

Maybe there should be. Maybe those exceptions aren't so far outside
the box as you might think. though.
- IConfig vs Config: In Java we don't use "I" which makes very difficult
to distiguish a class from an interface.

Actually, it's simple. An interface is used as the type of the
variable, and a class is used in the 'new' expression.

Less dismissively, there are conventions that support the distinction
and give meaning to names. Where sensible, think of interfaces as
pure type, and their names should speak to that. This usually results
in a descriptive adjective as a type name, e.g., "Serializable" or
"Comparable". Sometimes it results in a noun that is clearly of very
general applicability, e.g., "List" or "Collection". Usually the
interface has a non-compound name.

If one must decorate a name to distinguish that it's a class, not an
interface, apply that decoration only to the class. There is no need
to prefix an interface with "I" - the lack of decoration and the
abstract simplicity of the name ("Config") suffice to do that.

Decorations for class names usually attempt to be in the problem
domain and allude to concrete characteristics, e.g., "HashSet",
":ConcurrentLinkedQueue". These examples also show that class names
tend to be compound words with the implemented interface as part of
the name, as in "ArrayList". If one absolutely cannot use a domain-
meaningful name, one convention in Java is to append "Impl" to the
type name, e.g., "AbstractMarshallerImpl", and the other is the
"Abstract" prefix to which you alluded. (See below.)
- Absence of "m" or "m_" forces us to uses "this.foo = foo" when we have
arguments of the same name. (Even though I mostly dislike C-like
naming).

And prepending "this." is a problem because ...?
- Even Java does not conform to this purpose-implementation rule; you
have "Abstract" for abstract classses.

Well, the purpose of "AbstractFoo" is to provide an abstract
implementation of a "Foo" type, so actually the "Abstract" prefix does
conform to the convention that the name reflect purpose. Unlike
"Object" or "Class" in a class name, "Abstract" does not duplicate
some already-obvious keyword in the language.

Not all purposes in a program are in the problem domain. A few are
specific to implementation, and that is why classes like
"AbstractList" exist.
 
P

Pitch

Yes, I did. I said, "A name whose every part contributes to
understanding of the variable's role."

I asked for an example. Could you give one?

Actually, it's simple. An interface is used as the type of the
variable, and a class is used in the 'new' expression.

Of course, but ghow do we know which is which from their names? We
don't. So let's say I try "new SomeType()" and it gives me an error. But
if I the name was ISomeType I wouldn't have tried it in the first place.

It's faster to comprehand such names when you're working with non-
standard types.

Less dismissively, there are conventions that support the distinction
and give meaning to names. Where sensible, think of interfaces as
pure type, and their names should speak to that. This usually results
in a descriptive adjective as a type name, e.g., "Serializable" or
"Comparable". Sometimes it results in a noun that is clearly of very
general applicability, e.g., "List" or "Collection". Usually the
interface has a non-compound name.

Another thing here is that not all of us speak English. So it's
completely irrelevant if it is "List" or "Listable".
And prepending "this." is a problem because ...?

People forget these things. It seems to me that this imposes one extra
practice: "use this when assigning variables".

And remember that coding is all about prctices and little systems.

Well, the purpose of "AbstractFoo" is to provide an abstract
implementation of a "Foo" type, so actually the "Abstract" prefix does
conform to the convention that the name reflect purpose.

But it does not. You see, the Foo type doesn't even exist.

Have you ever had a situation like this? If you have types Foo and
AbstractFoo which one you'll say it's the base type? I'd say
AbstractFoo. So in my opinion Abstract denotes an abstract
implementation of this type, and Foo denotes a complete implementation.
It has nothing to do with purpose.
 
Joined
Apr 15, 2012
Messages
1
Reaction score
0
Problem with functions and Using ReentrantLock

I have a problem with functions when using reentrantLock.
My program start to generating random numbers and another thread using this number and calculating factorial of the number.
But it is not work... My second thread can printout number but cannot calculate factorial.
* My factorial function has not any problem...
 

Attachments

  • src.zip
    2.1 KB · Views: 78

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top