I need to insert into database which has two columns-
ID Primary Key String
Data String
So that means ID should be unique every time , otherwise it will throw a duplicate row in unique index exception while inserting. And I need to choose ID in between this range 1-100000
So that means each thread should be using unique id always-
Below is the multithreaded program I wrote that will insert into database with different unique id’s every time after getting from ArrayBlockingQueue.
So this program will be thread safe or not? Or is there any other better way to get the unique ID’s every time for each thread? Or the below program can cause duplicate row in unique index ?
private static LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
public static void main(String[] args) {
for (int i = 1; i <= 100000; i++) {
availableExistingIds.add(i);
}
BlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(200000, false, availableExistingIds);
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < noOfTasks * noOfThreads; i++) {
service.submit(new ThreadTask(pool));
}
}
class ThreadTask implements Runnable {
private BlockingQueue<Integer> pool;
private int id;
public ThreadTask(BlockingQueue<Integer> pool) {
this.pool = pool;
}
@Override
public void run() {
try {
dbConnection = getDBConnection();
preparedStatement = dbConnection.prepareStatement(INSERT_SQL);
id = pool.take();
preparedStatement.setString(1, String.valueOf(id));
preparedStatement.setString(2, ACCOUNT);
preparedStatement.executeUpdate();
} finally {
pool.offer(id);
}
}
}
The
pool.offer(id)means you put a used id back in the queue – so it can be reused later on by another thread. That is probably going to be an issue (since the queue is FIFO you will get a duplicate ID on the 100,001st insertion).In any case, it seems very complicated when a static
AtomicIntegerwould do the same thing without having to use a queue:Note: as commented, your database can probably assign unique IDs for you.