Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > What is so bad aboud Thread.stop() ?

Reply
Thread Tools

What is so bad aboud Thread.stop() ?

 
 
Arivald
Guest
Posts: n/a
 
      08-14-2013
W dniu 2013-08-14 01:45, markspace pisze:
> On 8/13/2013 4:08 PM, Arivald wrote:
>
>> And how to make sure such condition?
>> For example, by using specialized queues for input and output data from
>> thread. Queues written in a way that guarantee that it never is
>> inconsistent. Yes, it is possible, using java.util.concurrent.atomic it
>> is possible to write lock-free and thread safe queues.
>>
>> http://www.ibm.com/developerworks/library/j-jtp04186/

>
>
> That's a clever idea, but I'm not sure I'd want to rely on it working in
> production code. How much trouble is it really to not call
> Thread.stop()? That's what I see as the principle argument here. I'm
> not really convinced of the need for Thread.stop(), so all these
> workarounds seem moot.
>
> If one were really desperate, ok I can see having to resort to something
> like this, but it seems like there has to be several bad engineering and
> management decisions to get there.
>
>


I agree that Thread.stop() should be not used in standard operations.

But I still advise using lock-free queues, especially in high load and
highly multi-threading applications. Such structures does not need to
synchronize, so no thread will wait for other thread, resulting in
boosted performance.

Ans such highly multi-threading application can benefit from Thread.stop().
For example, lets assume application use MapReduce, and governing
thread/computer detects that one of threads works too long (other
threads/computers already finished same work). It may be error in code
or hardware malfunction that cause infinite loop.
In such case governing thread will use Thread.stop() to kill misbehaving
thread.

--
Arivald

 
Reply With Quote
 
 
 
 
Marcel Müller
Guest
Posts: n/a
 
      08-14-2013
On 14.08.13 01.08, Arivald wrote:
> So, if You can write thread in a way when it never create "inconsistent
> objects" that are accessible from other threads, calling Thread.stop()
> will be safe.
>
> And how to make sure such condition?
> For example, by using specialized queues for input and output data from
> thread. Queues written in a way that guarantee that it never is
> inconsistent. Yes, it is possible, using java.util.concurrent.atomic it
> is possible to write lock-free and thread safe queues.
>
> http://www.ibm.com/developerworks/library/j-jtp04186/


Funny. Almost 20 years ago I developed for a platform, where channel
communication was state of the art. (Channels are like queues without a
buffer. Transfers is synchronous.) In fact the programming scheme that
established when using this channels consequently had some interesting
properties:

- Race condition were gone.
- Dead-locks were gone.
- You simply start a new thread for almost any state machine in your
application.
- The code for most of this threads fits on one or two screens and
therefore is very easy to maintain.
- The resulting code has good scalability because of the many small tasks.
- Remoting is easy, because you only need to transfer the channel messages.
- Almost all memory objects belong to exactly one thread.
- The RAM locality is high. No cache line hopping.

The drawback is, that on recent PC architectures that many threads cause
a significant overhead, although most of them are sleeping most of the time.
On the particular platform the channel communication were machine
instructions as well as thread start was a single instruction. The
scheduler was also in hardware. And sleeping threads did not consume any
resources except for their stack memory. In fact there was not even a
repository with sleeping threads or something like a unique thread-id.
And if the implementation of a thread did not introduce recursions, the
required stack memory for each thread was exactly calculated and
adjusted by the compiler. So the stack for most of the (small) threads
was orders of magnitude smaller than nowadays.


Marcel
 
Reply With Quote
 
 
 
 
taqmcg@gmail.com
Guest
Posts: n/a
 
      08-14-2013
On Tuesday, August 13, 2013 6:22:33 PM UTC-4, Lew wrote:
> (E-Mail Removed) wrote:
>
> > I am trying to see what is new that Thread.stop brings to that consideration

>
> > versus other mundane and accepted Thread interactions.

>
>
>
> Seems to me that
>
> http://docs.oracle.com/javase/6/docs...precation.html
>
> explains it rather well.
>
> I found it fast via
>
> http://lmgtfy.com/?q=Java+dangers+of+Thread.stop
>
> You've cited part of this, presumably from the Javadocs:
>
> "This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the
> monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception
> propagating up the stack). If any of the objects previously protected by these monitors were in an
> inconsistent state, the damaged objects become visible to other threads, potentially resulting in
> arbitrary behavior."
>
> I'm not sure what else you need to know here. This is both normative and complete.
>
> --
>
> Lew


As discussed above in the thread my interest was that -- as this excerpt itself implies -- using Thread.stop merely initiates an exception which is then handled just as any other exception is. So what's special about it? In all of our discussion we seem to have only two characteristics that are special. The first is that ThreadDeath will not normally cause an error message. That seems pretty trivial. The second is that the exception can in principle happen anywhere in the stopped thread. However if it were easy to stop threads only in some TBD safe zone then it seems that using Thread.stop could be done robustly.

Since it seems that most commenters have limited experience with Thread.stop I've played a little with it myself. E.g., a test monitor class creates aset of worker threads. Each worker thread requests a task from the monitor, executes the task, reports the result back to the monitor, then asks forthe next task. The monitor periodically kills all threads older than somearbitrary value and creates a new replacement, caching the task that got cancelled to be rerun. The worker threads are only stoppable during the execution phase. Here's one of the classes:

package threadstoptester;

public class StoppableThread extends Thread {

private volatile boolean isStoppable = false;
private volatile boolean running = true;

synchronized protected void stoppable(boolean flag) {
if (!flag && !running) {
// Don't proceed to nonstoppable state if
// someone has already stopped the thread.
throw new ThreadDeath();
}
isStoppable = flag;
}

synchronized protected boolean running() {
return running;
}

synchronized public boolean doStop() {
if (isStoppable) {
isStoppable = false;
running = false;
this.stop();
return true;
} else {
return false;
}
}
}

The worker threads inherit this class, and the monitor thread calls the doStop method on the appropriate worker thread object which in turn calls Thread.stop
on the appropriate thread if the thread is currently stoppable.

My fairly simple implementation seems to run fine. Note that although it'snot especially complex, in terms of thread interactions this is much more involved than what I would normally do. Generally I just start one thread to do one task and throw it away when it's done. So this seems like a fairtest of whether there are some circumstances we can use Thread.stop robustly.

Of course I haven't proved anything... There could be subtle (or given my multithreading experience, obvious) bugs that just haven't surfaced in my limited testing. I've killed as many as ~40K threads so one might hope problems might emerge. Still so far this is play. But it doesn't suggest thatprograms are necessarily unstable when using Thread.stop, even promiscuously.

So where might this approach be useful:

1. Testing/running code that might include infinite loops due to bugs or user inputs.
- Better if single threaded
- Limited access to code
- Don't want overhead of starting new VM for each test
(or need some level of communication that makes separate VM inconvenient)
2. Stopping out of control tasks in some existing executor framework (e.g.., web server) where we need to clean up wayward threads.
- need to be able to identify 'stoppable' regions which may be hard.
3. As a potentially attractive alternative to the cooperative stopping mechanism in certain cases.
- When substantial code base might be implicated in cooperative approach.
- May require sandbox like approach.


The third alternative (and indeed all three) will be controversial, so I'llclose with an amplification of what I'm thinking there.

The cooperative Thread.interrupt() approach implies that the code that might be interrupted knows about this, i.e., the worker code is aware that there is some monitor. It needs to periodically check the interrupt flag and do something. This couples the invoker to the invoked in a way that's a bit unattractive. It's no big deal if it's just a simple loop to check but if there are lots of classes and methods that need to be instrumented it's not elegant.

If one has a set of code that is running where it's known that the invokingthreads are not affected except in some clearly defined way by the worker threads (e.g. a kind of sandbox), then using Thread.stop potentially decouples the monitor/invoker process from the worker code. In the right circumstances, I can imagine this being more attractive. My limited testing suggests that those circumstances need not be the null set.

That's not to say that others will or should agree with any of this, but thanks to both the user comments and my own explorations, I think I understand the issues much better. I'm intrigued by the responses discussing ways to do this that all the creation of dynamic objects that would be safe even in the presence of Thread.stop -- but that's probably more than I need to worry about now.


Thanks to all.

Regards,
Tom McGlynn
 
Reply With Quote
 
blmblm@myrealbox.com
Guest
Posts: n/a
 
      08-14-2013
In article <(E-Mail Removed)>,
Patricia Shanahan <(E-Mail Removed)> wrote:
> On 8/13/2013 1:18 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> ...
> > But to get back to your presumably-safe scenario, in which thread B
> > finishes normally. It seems reasonable to assume that all values
> > assigned in thread B should then be visible to other threads.
> > What I'm wondering, though, is whether that's explicitly required
> > by the Java memory model. (Yeah, yeah, really I should probably
> > just go read up on the memory model myself, but I thought someone
> > else might know, and that this might be an interesting point to
> > raise anyway.)

> ...
>
> "The final action in a thread T1 synchronizes-with any action in another
> thread T2 that detects that T1 has terminated. T2 may accomplish this by
> calling T1.isAlive() or T1.join()."
>
> http://docs.oracle.com/javase/specs/...ry.html#17.4.4
>


Thanks.

That seems fairly straightforward -- and I understand it to mean
"yes, the memory model does require that all values be visible,
assuming the thread doing the stop-another-thread then does a join()
to ensure that the stopped thread has finished".

--
B. L. Massingill
ObDisclaimer: I don't speak for my employers; they return the favor.
 
Reply With Quote
 
blmblm@myrealbox.com
Guest
Posts: n/a
 
      08-14-2013
In article <(E-Mail Removed)>,
<(E-Mail Removed)> wrote:
> On Tuesday, August 13, 2013 4:18:52 PM UTC-4, blmblm @ myrealbox. com wrote:
> > In article <(E-Mail Removed)>,
> >
> > <(E-Mail Removed)> wrote:
> >
> > > On Sunday, August 11, 2013 1:46:49 PM UTC-4, blmblm @ myrealbox. com wrote:

> >
> > > > In article <(E-Mail Removed)>,

> >
> > > >
> > > > <(E-Mail Removed)> wrote:
> > > >
> > > > ...
> > > > > You can use objects that are readonly to the stoppable thread to send
> > > > > information to that thread, and use objects that are read by the
> > > > > monitor (or other threads) only after the thread has successfully
> > > > > finished (or at least completed the tasks during which it may be
> > > > > stopped) to get information back. The fact that I might have stopped
> > > > > the thread in some circumstances doesn't mean I can't use objects
> > > > > created by it when I do let it finish.
> > > >

> >
> > > > That *sounds* plausible .... But it occurs to me that assigning values
> > > > to variable is no longer a simple matter -- with smart compilers and
> > > > caches and so forth, it's hard to be sure when the value will actually
> > > > be visible to other threads, which is presumably why the Java memory
> > > > model (with its "happens before" and so forth) exists. Can someone who
> > > > knows that model comment on how it might apply here?
> > > >
> > > > B. L. Massingill

> >
> > > It's certainly true that the memory model is abstruse, but that's true of
> > > interthread communications generally and not specific to killed threads.

> >
> >
> >
> >
> >
> > Agreed. (Do I seem to be saying otherwise?) Indeed, that's
> > the point I was trying to make in saying "that's why the Java
> > memory model exists" -- meaning that without a model, it would
> > be difficult if not impossible to say anything meaningful about
> > when one could rely on values being visible to other threads.
> >
> >
> > > If I have an object that is mutable by a thread that I might kill at some
> > > point, it would be pretty nifty if the fact that the thread was going to be
> > > killed in the future affected it before I killed it...a thiotimoline thread!

> >
> > Um, I don't get the connection between this and what I wrote. ?
> >
> > > And after the monitor kills a thread, it seems like discarding all
> > > potentially mutated objects should be a pretty robust way to limit the
> > > effects.

> >
> > Um, yes .... So you're saying if thread A kills thread B, to be
> > safe thread A should also discard any objects potentially mutated
> > by thread B?
> >
> > > But I'd agree that if there is a third thread involved, things get a lot more
> > > complex -- though again that's true of thread communication generally.
> > >

> >
> > Third thread? Now I'm really confused.
> >
> > But to get back to your presumably-safe scenario, in which thread B
> > finishes normally. It seems reasonable to assume that all values
> > assigned in thread B should then be visible to other threads.
> > What I'm wondering, though, is whether that's explicitly required
> > by the Java memory model. (Yeah, yeah, really I should probably
> > just go read up on the memory model myself, but I thought someone
> > else might know, and that this might be an interesting point to
> > raise anyway.)
> >
> >
> > > Tom McGlynn

> >
> >
> > B. L. Massingill
> >


> Sorry if I have confused things -- I'm not disagreeing with you I think. I'd
> be delighted to get an informed response that clearly referenced the formal
> memory model. However my particular issue in this thread is trying to
> understand what is especially dangerous about using Thread.stop(). The
> general complexity of inter-thread communications is a given, but not the
> topic I was hoping to explore.



Yes, I understood that part -- I was wondering whether part of the danger
might be ill-defined interaction with the memory model.


> In the two thread scenario we have four situations to consider:
>
> 1. Interactions between two threads where no stop occurs.
> - Presumably not affected by Thread.stop()!
> Monitor will stop thread:
> 2. ... but it hasn't happened yet.
> In this case it's difficult to see how Thread.stop() can have an
> effect before it is called -- unless the effect travels backward in time
> hence the reference to thiotimoline. For these two threads there
> should not be any difficulty in knowing if we are before or after
> the method call (in the case of the monitor) or before or after the
> initiation of the ThreadDeath interruption (in the case of the stopped
> thread)
> 3. ...after the Monitor has invoked the stop method.
> If any object the thread could have mutated is discarded immediately
> upon return from the stop call it's hard to see how any invalid state
> could get transferred to the monitor without some real weirdness in
> the memory model or some kind of tbd magic.
> We do need to make sure that the stopped thread dies.
> 4. ...While stop is running.
> I didn't refer to this in the earlier message, but
> the way stop is described, it doesn't actually do anything that should
> directly affect the memory (it just throws an exception). But I'd agree
> that an informed opinion would be helpful.
>
> My reference to three threads was intended to note that if we had other
> threads that could see to the objects the stopped thread could mutate, that
> it could be harder to ensure that invalid state did not escape, nothing more.
>
> So again, I don't think I'm disagreeing with your basic point regarding the
> memory model, but I am trying to see what is new that Thread.stop brings to
> that consideration versus other mundane and accepted Thread interactions.
>


Yes .... I think I'm still not quite getting your point about effects
*before* Thread.stop() is called, but I don't know that it's very
important anyway.

I think the point I might have been overlooking is that you're
proposing to be very careful not to use any objects potentially
modified by the stopped thread, and given that, maybe my concern
about whether their state is visible to other threads is a red
herring.

> Regards,
> Tom McGlynn
>


--
B. L. Massingill
ObDisclaimer: I don't speak for my employers; they return the favor.
 
Reply With Quote
 
markspace
Guest
Posts: n/a
 
      08-15-2013
On 8/14/2013 8:55 AM, (E-Mail Removed) wrote:

> The cooperative Thread.interrupt() approach implies that the code
> that might be interrupted knows about this, i.e., the worker code is
> aware that there is some monitor. It needs to periodically check
> the interrupt flag and do something. This couples the invoker to the
> invoked in a way that's a bit unattractive.



Several low level APIs in Java check for the interrupt flag, so if your
library is calling these methods, it will check for interrupts implicitly.

Object.wait(), Thread.sleep(), most of the IO library, probably some
more which I don't recall at the moment.

Also, if you're going to be dealing with threads at all, get yourself a
copy of Java Concurrency in Practice. It's *the* state of the art for
working with threads in Java.

I'll also link to this article by its author:

<http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>

I found your code a little baroque, so I wrote what I think is a simpler
example. Notice I never actually check the interrupt flag, but the code
terminates fine. If you comment out the call to interrupt(), then the
program does not terminate.

package quicktest;

/**
* @author Brenden Towey
*/
public class ThreadInterrupt
{
public static void main( String[] args ) throws Exception
{
Thread t = new Thread( new Wait() );
t.start();
Thread.sleep( 50 ); // wait a bit
t.interrupt();
t.join();
System.out.println( "Done!" );
}

private static class Wait implements Runnable {
@Override public synchronized void run() {
try { wait(); }
catch ( InterruptedException ex ) {}
}
}
}

OTOH hand if your library never makes any calls that do check for the
interrupt flag, well I'm pretty sure there's no chance of this working.
I'd still really prefer you find a way to make it work though; you're
spending a lot of time here to implement something that is fundamentally
broken (i.e., Thread.stop()).
 
Reply With Quote
 
taqmcg@gmail.com
Guest
Posts: n/a
 
      08-15-2013
On Wednesday, August 14, 2013 10:10:23 PM UTC-4, markspace wrote:
> On 8/14/2013 8:55 AM, (E-Mail Removed) wrote:
>
>
> > The cooperative Thread.interrupt() approach implies that the code
> > that might be interrupted knows about this, i.e., the worker code is
> > aware that there is some monitor. It needs to periodically check
> > the interrupt flag and do something. This couples the invoker to the
> > invoked in a way that's a bit unattractive.

>
> Several low level APIs in Java check for the interrupt flag, so if your
> library is calling these methods, it will check for interrupts implicitly..
> Object.wait(), Thread.sleep(), most of the IO library, probably some
> more which I don't recall at the moment.
>
> Also, if you're going to be dealing with threads at all, get yourself a
> copy of Java Concurrency in Practice. It's *the* state of the art for
> working with threads in Java.
>
> I'll also link to this article by its author:
>
>
>
> <http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>
>


It's an interesting article, but I think it tends to undercut your thesis that the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't needto couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider your worker thread as having three lines of code try, wait and catch, 66% of the worker code had to deal with handling the interrupt -- not especially decoupled.

>
> OTOH hand if your library never makes any calls that do check for the
> interrupt flag, well I'm pretty sure there's no chance of this working.
> I'd still really prefer you find a way to make it work though; you're
> spending a lot of time here to implement something that is fundamentally
> broken (i.e., Thread.stop()).


Which brings us back to my original question: In what way is it 'fundamentally' broken? That suggests that there is something inherently unsafe and unfixable in all circumstances not just dangerous and easily misused.

Your right though that I need to get the book...

Regards,
Tom McGlynn
 
Reply With Quote
 
taqmcg@gmail.com
Guest
Posts: n/a
 
      08-15-2013
On Wednesday, August 14, 2013 6:43:51 PM UTC-4, blmblm @ myrealbox. com wrote:
> In article <(E-Mail Removed)>,
>

....
>
> Yes .... I think I'm still not quite getting your point about effects
> *before* Thread.stop() is called, but I don't know that it's very
> important anyway.


Well that was mainly intended to be humorous, but it is important to understand how 'time' flows in the threads. We don't need to do anything special
until after we've invoked Thread.stop and at least in the two thread case both threads can easily know when to begin being careful.
>
>
>
> I think the point I might have been overlooking is that you're
> proposing to be very careful not to use any objects potentially
> modified by the stopped thread, and given that, maybe my concern
> about whether their state is visible to other threads is a red
> herring.
>

....
>
> B. L. Massingill
>


Right. That's one suggestion for how we might do things safely. That seems feasible to me, even natural. Typically my threads just do one thing that creates some object. If I discard the thread, I can ignore what it was starting to create.

Regards,
Tom McGlynn
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      08-16-2013
(E-Mail Removed) wrote:
> markspace wrote:
>> Also, if you're going to be dealing with threads at all, get yourself a
>> copy of Java Concurrency in Practice. It's *the* state of the art for
>> working with threads in Java.

>
>> I'll also link to this article by its author:
>>
>> <http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>

>
> It's an interesting article, but I think it tends to undercut your thesisthat the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't need to couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider


Goetz and others point out that you should never swallow InterruptedException, but re-interrupt the
thread after handling it.

> your worker thread as having three lines of code try, wait and catch, 66%of the worker code had to
> deal with handling the interrupt -- not especially decoupled.


--
Lew
 
Reply With Quote
 
taqmcg@gmail.com
Guest
Posts: n/a
 
      08-16-2013
On Thursday, August 15, 2013 8:35:39 PM UTC-4, Lew wrote:
> (E-Mail Removed) wrote:
>
> > markspace wrote:

>
> >> Also, if you're going to be dealing with threads at all, get yourself a

>
> >> copy of Java Concurrency in Practice. It's *the* state of the art for

>
> >> working with threads in Java.

>
> >

>
> >> I'll also link to this article by its author:

>
> >>

>
> >> <http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>

>
> >

>
> > It's an interesting article, but I think it tends to undercut your thesis that the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't need to couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider

>
>
>
> Goetz and others point out that you should never swallow InterruptedException, but re-interrupt the
>


Never is a bit too strong. The referenced article indicates that there is one circumstance under which it's OK to swallow the interrupt -- where the thread is about to terminate. That's actually the case in the example Markgave which swallows the exception. But overall that right and it just emphasizes the point that reliance upon the fact that a few methods will throwan InterruptedException doesn't go very far in getting a thread to terminate.

I did get a chance to look at Java Concurrency in Practice. It doesn't talk about Thread.stop except in a footnote that says not to use it. But the only justification given is a reference to the very text that I found to beunconvincing at the start of this thread. Their view of this isn't surprising. I suspect these are the very people whose input led the class to be deprecated in the first place -- they may have written that text! [This doesn't in any way mean to 'deprecate' their comment, just to note that it's likely not an independent statement of the badness of Thread.stop from the deprecation itself.]

Nonetheless there are some interesting tidbits to be gleaned from the theirchapter on terminating threads that might be relevant to this discussion.

Overall in discussing thread interrupts they note that one needs to set up a policy for handling interrupts. The whole chapter is addressing policiesfor how to handle interrupts and other terminations. That same would surely be true for Thread.stop. It could only be used robustly within some clear policy.

They dismiss the need for preemptive termination of threads with:
"The cooperative approach is required because we rarely want a task, thread, or service to stop immediately, since that could leave shared data structures in an inconsistent state." This suggests that a stop policy might include: "we want the thread stopped immediately, and we have no further interest in any shared any data structures".

Finally, in their discussion of the handling of exceptions thrown in threads, they note that task processing threads are the only places where it is appropriate for RunTimeExceptions to be handled. We have yet another footnote:

"There is some controversy over the safety of this technique; when a threadthrows an unchecked exception, the entire application may possibly
be compromised. But the alternative, shutting down the entire application, is usually not practical."

As discussed very early in this thread, it seems like handling Thread.stop is very similar to handling RuntimeExceptions. It's not coincidental that task managers are the primary area in which I could see Thread.stop being used effectively. If one is capable of handling a RuntimeException in a thread, it may not be much different handling Thread.stop.

Regards,
Tom McGlynn
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
oh perlbal you!!! you got what i need....but you dotn work with 5 16 johannes falcone Perl Misc 6 05-16-2013 08:11 PM
xmp, what to use instead of. myphplists@yahoo.com HTML 9 04-29-2013 03:35 PM
What is the reason for defining classes within classes in Python? vasudevram Python 6 04-24-2013 01:29 PM
what is the advantage of using maven for java standalone app mcheung63@gmail.com Java 13 04-16-2013 01:42 AM
What Linux freeware will blur faces & show all frames of a 30second AVI video? Danny D. Digital Photography 8 04-14-2013 10:18 PM



Advertisments