i trying grasp on synchronizing threads, don't understand problem i'm encountering.
can please me diagnose or, better, explain how can diagnose myself?
import java.util.arraylist; import java.util.list; import java.util.concurrent.cyclicbarrier; public class controller { public static void main(string[] args) { int numthreads = 0; list<thread> threads = new arraylist<>(); if (args.length > 0) { numthreads = integer.parseint(args[0]); } else { system.out.println("no arguments"); system.exit(1); } cyclicbarrier barrier = new cyclicbarrier(numthreads); int arr[][] = new int[10][10]; (int = 0; < numthreads; i++) { thread newthread = new thread(new threadableclass(barrier, arr)); threads.add(newthread); } (thread thread : threads) { thread.start(); } } }
there main method (above) accepts number of threads want command line argument. , there work-flow (below) aiming have increment elements in 2d array , print array before next thread has chance same:
import java.util.concurrent.brokenbarrierexception; import java.util.concurrent.cyclicbarrier; public class threadableclass implements runnable { private cyclicbarrier barrier; private int arr[][]; public threadableclass(cyclicbarrier barrier, int[][] arr) { this.barrier = barrier; this.arr = arr; } @override public void run() { long threadid = thread.currentthread().getid(); system.out.println(threadid + " starting"); (int = 0; < 10; i++) { changearray(); try { barrier.await(); } catch (interruptedexception | brokenbarrierexception e) { e.printstacktrace(); } } } private synchronized void changearray() { (int = 0; < arr.length; i++) { (int j = 0; j < arr.length; j++) { arr[i][j]++; } } printarray(); } private synchronized void printarray() { system.out.println(thread.currentthread().getid() + " printing: "); (int = 0; < arr.length; i++) { (int j = 0; j < arr.length; j++) { system.out.print(arr[i][j] + " "); } system.out.println(); } } }
imagining size of array 2x2, expected output this:
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 ... ... (10 * numthreads)-1 (10 * numthreads)-1 (10 * numthreads)-1 (10 * numthreads)-1 (10 * numthreads) (10 * numthreads) (10 * numthreads) (10 * numthreads)
instead, threads increment array, , begin printing on 1 another.
there nothing surprising result. create n threads. tell threads start. each threads run() starts with:
long threadid = thread.currentthread().getid(); system.out.println(threadid + " starting"); ...changearray();
going change shared array. after writing array, try sync (on barrier). late then!
the point is: have 10 different threadableclass instances. each 1 operating on own! synchronized
key word ... doesn't provide protection here!
because: synchronized prevents two different threads calling same method on same object. when have multiple objects, , threads calling method on different objects, there no locking! code boils down to:
threada call changearray() .. on threadb call changearray() .. on threadc call changearray() .. on
...
in other words: give n threads access shared array. allow n threads enter changearray() @ same time.
one simple fix; change
private synchronized void changearray() {
to
private void changearray() { synchronized(arr) {
in other words: make sure n threads have lock on same monitor; in case shared array.
alternatively: instead of making changearray()
method in threadableclass ... create class
arrayupdater { int arr[] update synchronized changearray() ...
then create one instance of class; , give same instance each of threads. sync'ed method prevent multiple threads enter!
Comments
Post a Comment