synchronized methods in a Runnable
===

I am writing a Runnable class that's packing messages together for some time or until a given size is reached before sending them over the wire. It is designed to allow other threads to change some internal parameters (e.g. the packet size) while it is running via some setter methods.  Is it correct to use an internal object lock to make parts of the `run()` logic mutually exclusive with the setters?

Something like that:

    public class Packer implements Runnable {
        private BlockingQueue<byte[]> msgQueue;
        private Object lock = new Object();
        private Packet packet;
        private boolean running = false;
    
        public synchronized void append(byte[] payload) throws InterruptedException {
            msgQueue.put(payload);
        }
    
        public synchronized void setPacketCapacity(int size) {
            synchronized (lock) {
                // check to see if we need to flush the current packet first, etc.
                packet.setCapacity(size);
            }
        }
        public void run() {
            running = true;
            while (running) {
                try {
                    byte[] msg = msgQueue.take();
                    synchronized (lock) {
                        packet.add(msg);
                        // check if we need to flush the packet, etc.
                    }
                } catch (InterruptedException ex) {
                    logger.warn("interrupted");
                    running = false;
                } catch (Exception e) {
                    logger.error(e);
                }
            }
            logger.warn("stop");
        }
    }

Relatedly, what's the right way for another thread to tell this runnable to stop (and flush)?

Since the `run()` method might be waiting on the internal queue `msgQueue`, it might not be sufficient to simply set `running=false` and I might have to interrupt the thread.  Alternatively, I could send a special "End Of Stream" message to the internal queue, but if the queue is full I might have to wait for a while before it gets accepted.