multithreading - Synchronizing threads according to a specific property of monitor object in Java -
my program imitating work on repository. resource must synchronized array cells
in repository
object (used monitor). threads (repothread
class) allowed add or subtract values to/from cell values of array, when no other thread doing same thing on the same cell. repothread
s actions(add/subtract) simultaneously long on different cells. cells in process considered "busy" , indexes stored in hashmap.
i have these classes (:
import java.util.hashset; import java.util.set; public class repository { private int[] cells; private set<integer> busycells; public repository(int size, int initialvalue) { busycells = new hashset<integer>(); cells = new int[size]; (int = 0; < size; i++) cells[i] = initialvalue; } public synchronized void add(int index, int amount, int threadid) { while (busycells.contains((integer) index)) { // cell busy try { system.out.println("thread" + threadid + "will wait add on cell" + index + ", busy cells:" + busycells); wait(); } catch (interruptedexception e) { } } // cell not busy busycells.add(index); cells[index] = cells[index] + amount; busycells.remove((integer) index); system.out.println("thread n." + threadid + " added " + amount + " cell " + index + ", new amount=" + cells[index] + ", busy cells: " + busycells); notifyall(); } public synchronized void remove(int index, int amount, int threadid) { while (busycells.contains((integer) index)) { system.out.println("thread n." + threadid + " tried remove " + amount + " cell " + index + "" + " amount " + cells[index] + "busy cells:" + busycells); try { wait(); } catch (interruptedexception e) { system.out.println("interrupted"); } } busycells.add(index); cells[index] = cells[index] - amount; busycells.remove((integer) index); system.out.println("thread n." + threadid + " removed " + amount + " cell " + index + "," + " new amount " + cells[index] + ", busy cells: " + busycells); notifyall(); } public int size() { return cells.length; } }
public class repothread extends thread { repository mon; int id; int addorremove; int index; int amount; public repothread(repository mon, int id, int addorremove, int index, int amount) { this.mon = mon; this.id = id; this.addorremove = addorremove; this.index = index; this.amount = amount; } public void run() { if (addorremove == 1) { mon.add(index, amount,id); }else if(addorremove==2){ mon.remove(index, amount, id); }else{ system.out.println("unknown operation requested"); } } }
public class testrepository { public static void main(string[] args) { repository repo = new repository(10, 5); repothread remover1 = new repothread(repo, 1, 2, 5, 8); remover1.start(); repothread remover2 = new repothread(repo, 2, 2, 5, 4); remover2.start(); repothread adder1 = new repothread(repo, 3, 1, 5, 4); adder1.start(); repothread adder2 = new repothread(repo, 4, 1, 5, 2); adder2.start(); repothread adder3 = new repothread(repo, 5, 1, 7, 4); adder3.start(); repothread adder4 = new repothread(repo, 6, 1, 5, 4); adder4.start(); } }
my problem seems no collisions occur because add
, remove
methods synchronized
. means when thread doing add or remove repository
object locked , no other thread can access array anyway since whole object locked , not busy cell.
what change supposed make threads able whatever want on repository object long doing on non-busy cell of cells
array?
if understand question, want lock more precisely on cell directly, right? if so...
one option replace synchronize synchronize block on cell object (if create array of cell object - meaning create cell class -).
// example cell [] cells = new cell[nb]; // initialize array need // later on, in remove or add synchronize (cells[i]) { // stuff }
another option lock through array of reentrantlock, 1 per cell.
reentrantlock [] locks = new reentrantlock[nb]; // fill array of reentranlock, 1 per cell locks[cellrank].lock(); try { // stuff } { lock[cellrank].unlock(); }
Comments
Post a Comment