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