Java File lock

I am using the following method to marshal user specific data to an XML file using Castor.  I would like to insure that multiple-threads are NOT saving the same user file at the same time..

Any suggestions would be appreciated

Thanks,
public boolean saveUserFilterFile() {
	Debug.debug(
		"WebViewUser.saveUserFilterFile() - entry",
		Debug.LEVEL_TRACE);
	if ((isCreateNewFilter()|| isAdministrator()) && saveFilter) {
		FilterGroupList expFl = new FilterGroupList();
	
		FileWriter writer  = null;
		String filename =
			ExpAppProperties.getExpFilterPath() + getUserName() + ".xml";
		String tempFileName = ExpAppProperties.getExpFilterPath() + "~~" + getUserName() + ".xml";
		try {
			//---( Clear current FilterGroupList in expUserProperties )---
			//---( Step through consolidated filter list copying user groups to expUserProperties )--
			for (Enumeration fl = allFilterGroupList.enumerateFilterGroup(); fl.hasMoreElements(); ) {
				FilterGroup fg = (FilterGroup) fl.nextElement();
				if ( fg.getUserFilterGroup() ) {
					expFl.addFilterGroup(fg);
				}
			}
			expUserProperties.setFilterGroupList(expFl);
 
			//---( Marshal expUserProperties )---
			writer = new FileWriter(tempFileName);
			Marshaller marshaller = new Marshaller(writer);
			marshaller.setNamespaceMapping("xsi","http://www.w3.org/2001/XMLSchema-instance");
			marshaller.setSchemaLocation("http://www.S4iSystems.com xsd/wvUserFilterFileSchema.xsd");
			marshaller.marshal(expUserProperties);
			if (writer != null ) {
				writer.close();
				// Rename temporary file to user file
				File tf = new File(tempFileName);
				File of = new File(filename);
				of.delete();
				tf.renameTo(of);
			}
		} catch (Exception e) {
			if (writer != null ) {
				try {
					writer.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			} else {
				e.printStackTrace();
			}
				Debug.debug(
					"Critical Error! WebViewUser.saveUserFilterFile(" +
						filename + 
						") - Save failed. " + e.getMessage(),
						Debug.LEVEL_ERROR);
				System.out.println(
					"Critical Error! WebViewUser.saveUserFilterFile(" +
						filename + 
						") - Save failed. " + e.getMessage());
				return false;
			}
		}
		return true;
}//--( end saveUserFilterFile() )--

Open in new window

sol400Asked:
Who is Participating?
 
basav_comConnect With a Mentor Commented:
Create a lock file ( tmp file ) to check that no one is using.
0
 
Thomas4019Connect With a Mentor Commented:
You could use java syncronization to do this. Basically you need one object that never changes in you code, it doesnt matter what it is. Java will make sure it is only in 1 synchronized block at any given time. Note that each thread must synchronize around the same integer.

Here is a link explaining sychronization.
http://java.sun.com/docs/books/tutorial/essential/concurrency/locksync.html
Integer holder = 0;
 
public void write()
{
   synchronized(holder)
   {
       //IO CODE
   }
}
 
public void read()
{
   synchronized(holder)
   {
       //IO CODE
   }
}

Open in new window

0
 
avya2kCommented:
you can have private static String object with any string and use it in synchronized block as follows
say private static String myStr="";
public boolean saveUserFilterFile() {
    synchronized(myStr){
       //method body
    }
}

This would ensure that at a time only one thread is using ur method
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
sol400Author Commented:
Hi,
I am NOT trying to single thread the method BUT only single thread multiple saves of the same file.  I can have end users saving unique files, multiple users saving the same file and a single user saving the same file in multiple threads.

Spencer
0
 
sol400Author Commented:
Hi,
So are you saying that the solution would be to create a temporary file with the same name of every file I save and then check for it's existance before starting the save. I would then delay and loop on the existance check. then delete the file when I exit.. This seems like a lot of overhead.
0
 
Thomas4019Commented:
Will the file only be edited by one program with multiple threads. Or is it possible there might be multiple Java programs running at the same time changing the files.
0
 
sol400Author Commented:
This is a web aplication where the xml file is used to contain single or group of end user specific persistance data. Each end user will have the file unmarshaled into their session object when they login to the web application.

I think I have solved the problem (I am testing now) based on the suggestion from basav.com.  I marshal the data into a temporary file then delete the orginal file & rename the temporary file.  It looks like all I have to do is check for the temporary files existance.
e.g.:
String tempFileName = ExpAppProperties.getExpFilterPath() + "~~" + getUserName() + ".xml";
File ckTemp = new File(tempFileName);
for ( int x = 0; x < 3; x++) {
      if (!ckTemp.exists()) {
            break;
      }
      try {
            Thread.sleep(2000);
      } catch (InterruptedException e) {
      }
}
      if (ckTemp.exists()) {
            ckTemp.delete();
}

0
 
objectsCommented:
all you need is to synchronize Thomas4019 suggested earlier.

> I am NOT trying to single thread the method BUT only single thread multiple saves of the same file.

so you just synch the block of code that does the save

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.