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

Popular posts from this blog

web services - java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer -

Accessing MATLAB's unicode strings from C -

javascript - mongodb won't find my schema method in nested container -