1 2 Previous Next 20 Replies Latest reply: Sep 12, 2006 6:09 PM by 796440 RSS

    Problems with synchronizing an element in an array

    807569
      I have a class that extends ArrayList. I have another class called "Elem" that works as elements for the ArrayList. Multiple threads will work on this list.

      When I get an element from the ArrayList I would like to lock only this element so another thread can delete other elements in the list.

      I have made this method for getting and locking an element:
           public String get(int id)
           {     
                String res ="No such file, try command list";
                int size = this.size();
                for (int i = 0; i<size;i++)
                {
                     Elem ifo = (Elem)this.get(i);
                     if(ifo.getId() == id)
                     {
                          synchronized(ifo)
                          {
                               try {
                                    Thread.sleep(4000);
                               } catch (InterruptedException e) {
                                    e.printStackTrace();
                               }
                               res = ifo.getData() + " Received";
                          }
                          break;
                     }
                }
                return res;
           }
      I have made the operation last for 4 seconds because I test if the object is locked with the follwing delete method:
           public synchronized String del(int id)
           {          
                String res =" no file";
                int size = this.size();
                for (int i = 0; i<size;i++)
                {
                     Elem ifo = (Elem)this.get(i);
                     if(ifo.getId() == id)
                     {
                          super.remove(ifo);
                          res = ifo.getId() + " deleted!";
                          break;
                     }
                }
                return res;
           }
      But when I run the program and start reading an element that I try to delete at the same time it gets deleted! Why does the "del" method not block until the element has been read?
        • 1. Re: Problems with synchronizing an element in an array
          807569
          For what you are actually trying to do I would suggest that the get method actually removes the element from the List. Perhaps you could rename this method getExclusive or something...

          Anyway when you are done put it back.

          Because synchonrization doesn't work in a fashion that your code demonstrates that you would like it to.
          • 2. Re: Problems with synchronizing an element in an array
            796440
            I have a class that extends ArrayList. I have another
            class called "Elem" that works as elements for the
            ArrayList. Multiple threads will work on this list.

            When I get an element from the ArrayList I would like
            to lock only this element so another thread can
            delete other elements in the list.
            That won't work. Deleting elements from the list modifies the list, not the elments, so you need to sync on the list. Only one thread at a time can add to or delete from a list.
            • 3. Re: Problems with synchronizing an element in an array
              807569
              Ok if I remove it then there is no point in using synchronized because the "del" method will never find it.

              Is it not possible to synchronize a single element in an array and keep other threads from manipulating it until the thread has finished doing its work?
              • 4. Re: Problems with synchronizing an element in an array
                807569
                Ok if I remove it then there is no point in using
                synchronized because the "del" method will never find
                it.
                Well there is still is a point to synchronizing that method. Otherwise chaos!
                Is it not possible to synchronize a single element in
                an array and keep other threads from manipulating it
                until the thread has finished doing its work?
                No.
                • 5. Re: Problems with synchronizing an element in an array
                  796440
                  Ok if I remove it then there is no point in using
                  synchronized because the "del" method will never find
                  it.
                  If there are multiple threads adding to and/or removing from the list, you must sync all those remove operations on a common lock--usually the list itself.

                  Is it not possible to synchronize a single element in
                  an array and keep other threads from manipulating it
                  until the thread has finished doing its work?
                  You can sync on a single element, of course--it's just another object. But that does not help you if you're removing that object, because any add or remove operation will operate on data that is shared by all add and remove operations.
                  • 6. Re: Problems with synchronizing an element in an array
                    807569
                    Ok but that is pretty ineffective. In real systems its possible for a user to read one file on the disk while deleting another. I try to simulate a disk with an ArrayList and obtain the same functionality but since its impossible how is it acomplished in real systems?
                    • 7. Re: Problems with synchronizing an element in an array
                      807569
                      Ok but that is pretty ineffective. In real systems
                      its possible for a user to read one file on the disk
                      while deleting another. I try to simulate a disk with
                      an ArrayList and obtain the same functionality but
                      since its impossible how is it acomplished in real
                      systems?
                      What is pretty ineffective? My solution? My solution is perfectly effective and provides the functionality you seek.

                      If you really wanted to do it like a disk then I would wrap your objects in an object that has a boolean lock added to it.

                      When you retrieve the element then you mark the item as locked (all in a synchronized method).

                      Then when you go to delete you don't allow locked items to be deleted.

                      Of course you still have to release the lock...
                      • 8. Re: Problems with synchronizing an element in an array
                        807569
                        No it was not your suggestion that I found ineffctive its the fact that its not possible to make multiple operations on a list at the same time.
                        • 9. Re: Problems with synchronizing an element in an array
                          796440
                          Ok but that is pretty ineffective.
                          No, it works well in many situations.

                          In real systems
                          its possible for a user to read one file on the disk
                          while deleting another.
                          That doesn't necessarily translate directly to what you've said so far.

                          I try to simulate a disk with
                          an ArrayList and obtain the same functionality but
                          since its impossible how is it acomplished in real
                          systems?
                          This sounds different from what you were asking about earlier.

                          WIthout more details about what you're trying to do and how you're trying to implement it, it's hard to advise you how to solve your problem.

                          Also, note that even things that appear to be "simultaneous" may have synchronized pieces that happen so quickly that you can't tell the difference.
                          • 10. Re: Problems with synchronizing an element in an array
                            DrClap
                            Is it not possible to synchronize a single element in
                            an array and keep other threads from manipulating it
                            until the thread has finished doing its work?
                            No.
                            Actually, you could do anything you liked if you encapsulated the array in an object and required all access to the array to be via methods of the object. But just leaving the array out there on the floor for everybody to kick at, "no" is the answer.
                            • 11. Re: Problems with synchronizing an element in an array
                              796440
                              No it was not your suggestion that I found ineffctive
                              its the fact that its not possible to make multiple
                              operations on a list at the same time.
                              Nobody said it's not possible to make multiple operations on a list at the same time.

                              What we said is that you must synchronize any operations that add or remove data in a java.util.ArrayList (and other standard collections) because those add and remove operations modify shared data.

                              Anytime multiple threads might be modifying shared data, you must synchronize. Or else you must be able to detect and correct any inconsistencies that arise from lack of syncing.
                              • 12. Re: Problems with synchronizing an element in an array
                                796440
                                Is it not possible to synchronize a single
                                element in
                                an array and keep other threads from manipulating
                                it
                                until the thread has finished doing its work?
                                No.
                                Actually, you could do anything you liked if you
                                encapsulated the array in an object and required all
                                access to the array to be via methods of the object.
                                But there'd still have to be synchronization at some point in those methods, because shared data might be modified by multiple threads.
                                • 13. Re: Problems with synchronizing an element in an array
                                  807569
                                  Ok here is what I am trying to do.


                                  1) Thread 1 get an element from list A. At the SAME time thread 2 deletes a different element from list A.

                                  2) Thread 1 get an element from list A. At the same time thread 2 tries to delete the same item but gets blocked since thread 1 is reading it.


                                  currently only serial execution works, since all the methods on the list are synchronized.
                                  • 14. Re: Problems with synchronizing an element in an array
                                    796440
                                    Ok here is what I am trying to do.


                                    1) Thread 1 get an element from list A. At the SAME
                                    time thread 2 deletes a different element from list
                                    A.
                                    Everything I've said still applies. What do you mean "at the SAME time"? And why does it have to be "at the SAME time"? What if whatever triggers cause the two actions happen "at the SAME time," but the actual actions happen a millisecond apart?


                                    currently only serial execution works, since all the
                                    methods on the list are synchronized.
                                    Again, anytime you're accessing shared data from multiple threads, you must synchronize. That syncing may be very, very brief--say just to atomically update a counter or "available" bitmap or something, but if there's shared data--such as a bitmap that keeps track of which slots are used--read/updates, like "find an available one, mark it used, and give me its index"--must be atomic, so there must be some synchronization.

                                    Or else different threads get different sections of the array assigned to them.
                                    1 2 Previous Next