On Mon, Oct 12, 2009 at 7:18 PM, Nathan Beyer <nbe...@gmail.com> wrote:
> Honestly, the synchronization probably isn't appropriate on any of the > accessor/mutators - the granularity isn't correct. The locking > probably needs to encompass the entire method on DatagramSocket while > working on a particular DatagramPacket. Realistically, you don't want > the packet to change while processing. > A test shows that the RI uses synchronized. The following program doesn't complete: public static void main(String[] args) throws Exception { byte[] data = new byte[] { 1, 2, 3, 4, 5 }; final DatagramPacket datagramPacket = new DatagramPacket(data, data.length); ExecutorService executorService = Executors.newFixedThreadPool(1); synchronized (datagramPacket) { Future<byte[]> future = executorService.submit(new Callable<byte[]>() { public byte[] call() throws Exception { return datagramPacket.getData(); } }); byte[] fromAnotherThread = future.get(); System.out.println(Arrays.toString(fromAnotherThread)); } } Unfortunately, the concurrency support is shallow and not useful. Despite the fact that the RI has synchronized statements, it fails to defensively copy the data array: public static void main(String[] args) throws Exception { byte[] data = new byte[] { 1, 2, 3, 4, 5 }; final DatagramPacket datagramPacket = new DatagramPacket(data, data.length); System.out.println("arrays are defensively copied? " + (data != datagramPacket.getData())); } As a consequence, one thread could mutate the data array while another thread is consuming it. Regardless, it looks like synchronized and no defensive copying is the key to compatibility with the RI.