Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: Handling IO Synchronization

  1. #1
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Handling IO Synchronization

    I have a class (WriteExcel) which writes to an excel file. For those who don't know, Excel doesn't handle multiple access well (or at all).
    I then have another class (WriteManager) which creates a new thread for each write command, and then calls a method from the WriteExcel class.
    Other classes in my project calls methods from WriteManager to send their requests.
    My situation looks like this:
    1) Thread 1: Someclass -> WriteManager.write1stPage(write) -> Creates Thread 2 -> WriteExcel.write1stPage(write) -> Start Excel Write
    2) Thread 1: Someclass -> WriteManager.write2ndPage(write) -> Creates Thread 3 -> WriteExcel.write2ndPage(write) -> Start Excel Write
    3) Thread 1: Someclass -> WriteManager.write3rdPage(write) -> Creates Thread 4 -> WriteExcel.write3rdPage(write) -> Start Excel Write
    4) Thread 2: Finished writing and ready to save -> Throws exception due to multiple Excel access
    5) Thread 3: Finished writing and ready to save -> Throws exception due to multiple Excel access
    6) Thread 4: Finished writing and ready to save -> Throws exception due to multiple Excel access

    I need to figure out a way to restrict access to WriteExcel until the writing is finished. So I need something like this:
    1) Thread 1: Someclass -> WriteManager.write1stPage(write) -> Creates Thread 2 -> WriteExcel.write1stPage(write) -> Start Excel Write
    2) Thread 1: Someclass -> WriteManager.write2ndPage(write) -> Creates Thread 3 -> Waits Until WriteExcel is free
    3) Thread 1: Someclass -> WriteManager.write3rdPage(write) -> Creates Thread 4 -> Waits Until WriteExcel is free
    4) Thread 2: Finished writing and ready to save -> Saves and frees WriteExcel
    5) Thread 3: WriteExcel is free -> WriteExcel.write2ndPage(write) -> Start Excel Write
    6) Thread 3: Finished writing and ready to save -> Saves and frees WriteExcel
    7) Thread 4: WriteExcel is free -> WriteExcel.write3rdPage(write) -> Start Excel Write
    8) Thread 4: Finished writing and ready to save -> Saves and frees WriteExcel

    What is currently the best approach in java for handling this sort of situation?
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/


  2. #2
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,320
    Thanks
    181
    Thanked 832 Times in 772 Posts
    Blog Entries
    5

    Default Re: Handling IO Synchronization

    I'm unclear of the need for Thread's 2-4. But be that as it may, if you need to write to the file asynchronous relative to Thread 1, you might consider using a queue - for instance create a thread pool of size 1 using Executors...in this manner only one write will occur at any given time and they will occur sequentially

  3. #3
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Handling IO Synchronization

    The other threads were being created because I had no way of really monitoring when certain write requests were sent, and each write request needed to run on a thread other than the one which called it.

    I actually managed to come up with a somewhat elegant approach. Instead of multiple threads, I created a single writing thread. The writing thread contains a queue of requests, which it cycles through. When the queue runs out, the thread tells itself to wait. When a new request is added to the queue, the thread is told to continue on. This way I don't have the thread looping continuously in the background for no reason.

    Tell me what you think about this. I've ran it a few times with perfect success, but that doesn't mean there isn't something serious I've overlooked. This does require a class: WriteRequest, which just contains a type and a payload to pass onto the excel writer.
    public class ServiceManager {
        private WriteDatabaseThread writeDatabaseThread;
     
        public void addRequest(WriteRequest request) {
            this.writeDatabaseThread.requests.add(request);
            synchronized (this.writeDatabaseThread) {
                this.writeDatabaseThread.notifyAll();
            }
        }
     
        public void setWriteDatabaseInterface(WriteDatabaseInterface databaseInterface) {
            this.writeDatabaseThread = new WriteDatabaseThread(databaseInterface);
            this.writeDatabaseThread.start();
        }
     
        public void write1stPage(...) {
            if (this.writeDatabaseThread == null) {
                return;
            }
            this.addRequest(new WriteRequest(TYPE_ONE,...));
        }
     
    	public void write2ndPage(...) {
    		if (this.writeDatabaseThread == null) {
                return;
            }
            this.addRequest(new WriteRequest(TYPE_TWO,...));
    	}
    	...
    }
    public class WriteDatabaseThread extends Thread {
        public volatile Queue<WriteRequest> requests = new LinkedList<>();
        private WriteDatabaseInterface writeDatabaseInterface;
     
        public WriteDatabaseThread(WriteDatabaseInterface writeDatabaseInterface) {
            this.writeDatabaseInterface = writeDatabaseInterface;
        }
     
        @Override
        public void run() {
            while (true) {
                try {
                    if (this.requests.size() == 0) {
                        synchronized (this) {
                            this.wait();
                        }
                    }
                    WriteRequest request = this.requests.poll();
                    if (request != null) {
                        ... payload = request.getPayload();
                        switch (request.getType()) {
                            case TYPE_ONE: {
                                this.writeDatabaseInterface.write1st(...);
                                break;
                            }
                            case TYPE_TWO: {
                                this.writeDatabaseInterface.write2nd(...);
                                break;
                            }
                            ...
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  4. #4
    Senior Member
    Join Date
    Jul 2013
    Location
    Europe
    Posts
    666
    Thanks
    0
    Thanked 121 Times in 105 Posts

    Default Re: Handling IO Synchronization

    I would advice you to use a collection that does not throw concurrent modification exceptions when working with multithreading. For example the CopyOnWriteArrayList for the queue of write requests.
    You could have the thread do all requests and clear the list periodically.

  5. #5
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Handling IO Synchronization

    Would the ConcurrentLinkedQueue collection resolve that issue? ConcurrentLinkedQueue (Java Platform SE 7 )
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  6. #6
    Senior Member
    Join Date
    Jul 2013
    Location
    Europe
    Posts
    666
    Thanks
    0
    Thanked 121 Times in 105 Posts

    Default Re: Handling IO Synchronization

    If the API says that its safe against concurrent modification exceptions / save for multithreading then yes. But linked lists are usually slower then array lists in most circumstances.

Similar Threads

  1. Is this a correct use of synchronization?
    By Cornix in forum Threads
    Replies: 3
    Last Post: September 2nd, 2013, 06:21 PM
  2. synchronization
    By bassie in forum What's Wrong With My Code?
    Replies: 2
    Last Post: January 12th, 2013, 08:29 AM
  3. problem in synchronization
    By codenoob in forum Threads
    Replies: 3
    Last Post: December 8th, 2011, 08:29 AM
  4. synchronization problems
    By stroodlepup in forum Threads
    Replies: 2
    Last Post: February 28th, 2011, 09:26 AM
  5. synchronization
    By bbr201 in forum Java Theory & Questions
    Replies: 6
    Last Post: August 29th, 2010, 09:32 AM