简体   繁体   中英

Java client Side locking Error

I am trying to understand Client Side locking.

I was on the impression that if we do synchronized (elements) {} as in the below code, the whole list will be locked and no addition or deletion will not happen until the thread exit the monitor. But i can able to add the elements in the addListElement method and i get Exception in thread "Thread-0" java.util.ConcurrentModificationException .

How the client side locking works in java?

public class ClientLocking {

    public static void main(String args[]) {
        System.out.println("Hello World!!");
        ClientLocking c = new ClientLocking();
        c.startProcess();
    }

    private final List<String> elements = new ArrayList<String>();

    private void startProcess() {

        addListElement("e1");
        addListElement("e2");
        addListElement("e3");

        MyThread t = new MyThread();
        t.start();

        addListElement("e4");
        addListElement("e5");
        addListElement("e6");

    }

    private void addListElement(String element) {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (elements.add(element)) {
            System.out.println("Added : " + element);
        } else {
            System.err.println("Not Added : " + element);
        }
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            try {

                synchronized (elements) {
                    Iterator<String> it = elements.iterator();
                    while (it.hasNext()) {
                        String el = it.next();
                        System.out.println("Printing : " + el);
                        Thread.sleep(500); // Some processing
                    }
                }

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Synchronization only works when all relevant code (all "critical sections") is making use of the locks.

In your example, run uses synchronized(elements) , but addListElement does not. As a result, it does not care about your locking scheme.

All your synchronized block does currently is prevent two threads running "run" at the same time (for the same list). Any other code you want to be aware of the lock also has to include synchronized blocks (with the same monitor object).

You haven't synchronised the addElement method itself.

Even the thread is holding the monitor for elements, the add method does not try to get the monitor.

There are two ways. First, Mark the whole add method as synchronised (this works without a monitor object) So this would only allow one thread to call add method at a time. But this is not what you tried to achieve.

A solution would be that your addMethod itself would try to get the monitor. So place another block of synchronised(element) around the body of the addElement method.

But you have to think of, that both threads really use the same monitor object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM