java - how to make sure int is assigned a unique id for that thread -
java - how to make sure int is assigned a unique id for that thread -
i need insert database has 2 columns-
id primarykey string business relationship string so means each thread should using unique id , need store same id in account column also. suppose if id 1 in database should stored
id business relationship 1 somestring+1 2 somestring+2 3 somestring+3 .... .. 100 somestring+100 i concatenating userid string in business relationship column.
below multithreaded code spawn multiple threads- , each thread getting new unique id everytime using atomicinteger that. , insert id id column , append id account column
but somehow in below programme have seen in database is-
id business relationship 1 string+2 2 string+1 3 string+3 which not right. should this-
id business relationship 1 string+1 2 string+2 3 string+3 below code
public static void main(string[] args) { final int noofthreads = 4; final int nooftasks = 10; final atomicinteger id = new atomicinteger(1); executorservice service = executors.newfixedthreadpool(noofthreads); (int = 0; < nooftasks * noofthreads; i++) { service.submit(new task(id)); } } class task implements runnable { private final atomicinteger id; private volatile int userid; public task(atomicinteger id) { this.id = id; } @override public void run() { dbconnection = getdbconnection(); preparedstatement = dbconnection.preparestatement(constants.insert_oracle_sql); userid = id.getandincrement(); preparedstatement.setstring(1, string.valueof(userid)); preparedstatement.setstring(2, constants.getaaccount(userid)); preparedstatement.executeupdate(); } } and below constants class have made immutable.
public final class constants { public static string a_account; public final static string insert_oracle_sql = "insert xmp_test" + "(" + "id, a_account) values" + "(?, ?)"; public static string getaaccount(int userid) { a_account = "{\"lv\":[{\"v\":{\"userid\":"+userid+"},\"cn\":1}]}"; homecoming a_account; } } can tell me wrong doing here? believe it's happening because of thread safety issue. multiple threads modifying userid integer guess , that's why getting written wrongly database.
how can prepare problem?
the major problem see not task.userid, rather constants.a_account: if 2 separate threads phone call getaaccount @ same time, they'll both set constants.a_account , both read it, can end both having same value, or each having other's value, or whatnot. prepare this, can utilize local variable instead of static field:
public static string getaaccount(int userid) { final string ret = "{\"lv\":[{\"v\":{\"userid\":"+userid+"},\"cn\":1}]}"; homecoming ret; } or dispense variable:
public static string getaaccount(int userid) { homecoming "{\"lv\":[{\"v\":{\"userid\":"+userid+"},\"cn\":1}]}"; } (you you've made constants immutable, that's not true. instances of constants immutable, because have no fields @ all; constants has publically modifiable field, it's very mutable!)
more generally, shouldn't using fields temporary values needed within specific method, , during single phone call it. when it's not synchronization problem, it's maintenance problem. example, task not need volatile int userid; userid should local variable within run method.
also, i'd recommend wrapping atomicinteger in own class, incrementingcounter or something, offers 1 method, called (say) getnewid. getnewid class has deal coordination between threads. other classes can made threadsafe regular techniques (immutability, existing within single thread, etc.).
java multithreading thread-safety atomicity
Comments
Post a Comment