Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

How to Operate Safely  RSS feed

 
qingwu wang
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is it Thread-Safe?
if not,How can I make it?


Thanks a lot!
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
your code is not complete as you have not listed all the methods.
I assume you are using File.mkdirs() method to create the directory hierarchy represented by your File instance.

If yes, then that method is not thread-safe. This is a bug for the same.

Infact the problem is that during your program is running someone else(not necessarily your program) may create one of the directories in the hierarchy that you are creating. This will lead to your mkdirs() to fail. So, there is no way to actually do that unless at the OS level you make mkdirs() as atomic.
However, if you just want your program to be thread-safe then you can write a single method to create mkdirs() that everyone in your application uses:



Disclaimer: I have written the above code in this editor window so it may have some spelling mistakes.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the bigger problem here is that you're not checking the return value of mkdir() (or more properly, mkdirs() as Nitesh notes). This can fail for a variety of reasons, only some of which are because another thread or process interfered. It be because:
  • the parent directories don't exist (this is fixed by using mkdirs() rather than mkdir()
  • you don't have the appropriate permission to create a directory here
  • the directory already exists (which was tested, but a concurrent process outside the JVM may have created it after the last test)
  • a file already exists with the same name as the directory
  • the path you have provided is not a legal name for a directory name or path, according to the OS
  • another random reason which I don't remember right now

  • I would argue that any halfway-decent method should check this return value and, at the very least, log it if there was a problem. Note that I do not consider File methods like mkdir(), mkdirs(), delete() or rename() to be even halfway decent, because they can fail without throwing an exception, and give no useful feedback about why they failed. There's no excuse for hiding the reason for failure in Java - that's one of the key strengths of Java's exception handling mechanism. If you have the misfortune of depending on the haphazardly craptastic methods of the File class, you need to check their return values to verify that they really do what they're supposed to do. It's sad that such piss-poor method implementations were allowed to exist in the JDK, but we must deal the hands we are dealt.
     
    Nitesh Kant
    Bartender
    Posts: 1638
    IntelliJ IDE Java MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Jim Yingst:
    I think the bigger problem here is that you're not checking the return value of mkdir() (or more properly, mkdirs() as Nitesh notes).

    Absolutely, Jim, this is one thing i missed.

    Additionally, I *think* the File.mkdirs() method should not return false or fail if the directory already existed. The intention was to create the directory and so if the directory already existed, it should return an appropriate message (as you suggested), though i am not very convinced with throwing an exception. Exception probably must be thrown if the directory did not exist and it was not created(for the reasons that you mentioned)
    Anyways, that is the way it is, as you correctly said "we must deal the hands we are dealt"
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!