I am working for multithreaded application, so i have a thread which has one Global ArrayList variable, I am fetching list of values from database and assigning it to that variable. I have restricted how many list should fetch, to 100. In backend i am using hibernate.
I have kept this thread running in background periodically, But what i wanted to do that, whenever this thread runs, it will fetch next 100 list of items. And also i don't want to use static and don't want to maintain it in a database, i am confuse how to maintain a counter that will tell my fetching method that next 100 item to fetch. can anybody help, how can i achieve this? Following is my code sample,
public class DemoThread implements Runnable {
private ArrayList <<>> samplePojoList = null;
#Override
public void run() {
MyDaoClass dao = null;
try {
// this dao method fetching list of 100 results from database,
// for each iteration i want to fetch next 100 result from
// database
samplePojoList = dao.getSampleList();
} catch (Exception e) {}
}
}
You can very well make use of ThreadLocal variable in this case.
Please see example below:
private ThreadLocal<Integer> counter = new ThreadLocal<Integer>();
Here is a simplified example how you can pass a counter to your threads and maintain a synchronized count among your consumer threads. In order to maintain the counter count consistent among threads, it should be accessed and increased in the synchronized block.
My assumption is that you want a counter to be shared among all your consumer threads, not one counter per consumer thread.
class Counter{
int count = 0;
}
class MyThread implements Runnable {
Counter counter;
MyThread(Counter counter){
this.counter = counter;
}
public void run() {
int count;
synchronized(counter){
count = counter.count;
counter.count++;
}
// fetch 100 times the value of this counter
System.out.println(count); // just a stub code
}
}
public class CounterDemo {
public static void main(String[] args) {
Counter counter = new Counter();
MyThread t = new MyThread(counter);
new Thread(t).start();
}
}
You can use AtomicReference to achieve the same.
Sample code for String:
String initialReference = "value 1";
AtomicReference<String> someRef =
new AtomicReference<String>(initialReference);
String newReference = "value 2";
boolean exchanged = someRef.compareAndSet(initialReference, newReference);
System.out.println("exchanged: " + exchanged);
You can replace String with ArrayList in above example.
Have a look at this SE post for more details:
When to use AtomicReference in Java?
Related
Let us say I have two classes, A main class and a Thread class as follows:
public class A {
public static void main(String []args){
int count = 0;
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd of the thread class
//and when countOfAdd value is in multiples of 5 I want to print a statement
}
}
class B extends Thread {
int countOfAdd;
#Override
public void run(){
//on value received
count+=1;
}
}
I don't know whether this is possible or not. If it is possible how to do it
Thanks in advance.
The normal way to do that is a queue.
Create a queue and make references to it available to both threads.
The main thread should add() an element to the queue (e.g. the amount of increment).
The other thread should poll() the queue and use this information to update its internal state.
This way none of the intermediate updates are going to be lost between the threads.
The quick and dirty way is direct access and locking.
Both of your threads can keep a reference to a common piece of data, and a common lock object (which can just be a Object commonLock = new Object()).
Every time either thread needs to access the data member, they do it holing a lock, e.g.:
synchronized (commonLock) { commonCount +=1; } // One thread.
synchronized (commonLock) { if (commonCount > 1) {...} } // Another thread.
This is harder to reason about, but can be made serviceable if the number of accesses in each thread is made small, preferably just one.
I don't know why you are using Thread here but anyway.
1. Without Thread
public class A {
public static void main(String []args){
int count = 0;
B objectB = new B();
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd
//of the thread class and when countOfAdd value is in multiples of 5
//I want to print a statement
objectB.setCount(YourInput);// set your value
if(objectB.getValue()%5==0){
//do your task
}
}
}
class B {
int countOfAdd;
public int getCount(){return countOfAdd;}
public void setCount(int ){this.countOfAdd =countOfAdd;}
}
2. With Thread
Use Pub-sub pattern
Implementation of pub sub pattern in Java
Following is my code
class ExtendsThread extends Thread {
private int counter = 0;
/* should I need to make Display synchronize ?*/
public void Display() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
public void run() {
Display();
}
}
public class MyMain{
public static void main(String args[]) throws Exception {
//Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
output is :
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
I read that When you extends Thread class, each of your thread creates unique object and associate with it hence counter is always one.
Now my question is do I need to synchronize Display method?
AS counter is always 1 because it is separate object, so we need not to use synchronize.
is it correct?
You could synchronize access to a static counter, or you can use an AtomicInteger, which will handle the threadsafety for you...
class ExtendsThread extends Thread {
private static final AtomicInteger counter = new AtomicInteger(0);
public void Display() {
System.out.println("ExtendsThread : Counter : " + counter.incrementAndGet());
}
public void run() {
Display();
}
}
The way you have it now, there is one instance of counter for each instance of ExtendsThread. If you want counter (or any field) to be shared among all of the instances of a specific class, you have to make them static. Since you'll have multiple threads accessing the now static counter, you'll have to control access to them so they don't cause a race condition. This is where AtomicInteger comes in - it handles all of that for you.
In your example, each thread has its own copy of the counter variable, so there's no synchronization required. If the variable was shared between threads, then there should be synchronization.
synchronize is used to prevent two threads to execute the method at the same time. You need to use synchronize but the key factor here is that you also need to make the variable static, so all the instances of the class share the same variable.
In your example the only way to get different values is making the variable static like this:
private static int counter = 0;
If you do not want problems of holds with the threads is recommendable sinchronize the method.
I have a potential race condition in my Java code that uses a BlockingQueue, and I'd like to know how to modify the code to avoid it:
private static BlockingQueue<FileToFTP> ftpQueue = new LinkedBlockingQueue<FileToFTP>();
private static boolean shuttingDown = false;
private static FileToFTP pendingFile = null;
private static int uploadsPending = 0;
private static Thread ftpThread = new Thread(new Runnable() {
public void run() {
try {
for(;;) {
FileToFTP f2f = ftpQueue.take(); // this blocks until there is something to take
// FIXME: If the main thread takes over right
// at this instant, then uploadsRemaining()
// is not correct!!
uploadsPending = 1;
int qs = ftpQueue.size();
logIt(qs, f2f);
pendingFile = f2f;
if(!doUploadFile(f2f.getPath(), f2f.getFilename(), f2f.getRenameTo(), f2f.isBinary())) {
if(shuttingDown) {
log.info("Upload " + f2f + " failed!");
} else {
ftpQueue.offer(f2f); // put it back on to retry later
}
uploadsPending = 0;
} else {
pendingFile = null;
uploadsPending = 0;
}
if(qs == 0) logIt("");
}
} catch (InterruptedException consumed) {
// Allow thread to exit
}
}
});
public static int uploadsRemaining() {
return ftpQueue.size() + uploadsPending;
}
Please see the "FIXME" comment in the code. Thanks!!
Maybe I'm misinterpreting what you want, but it sounds like you may be better off using an ExecutorService to actually run things. You can create those using Exectors.newSingleThreadExecutor() or Executors.newFixedThreadPool(2) (2 being an example of the number of threads for it to use).
You can then either .execute or .submit Runnables on the ExecutorService. submit will return a Future<T> object that can be used to track the status of a particular job submitted to an ExecutorService.
Having said that, you may need to create a new class to do it as the Runnable / Callable class would need to have a FileToFTP variable in it. (Side note: I try to avoid inner classes, so if you're wondering why I didn't suggest doing it that way...)
The problem then becomes "how do I tell how many files are pending?" Unfortunately, the only easy way is to make it a static property of another class... with either static get/set methods or as a public/protected property. An AtomicInteger is ideal for this, so you may want to consider using one as a protected static one in your calling class. It has dedicated increment/decrement commands as well as ones that both adjust the value and return it.
So here I write three simple class to inspect how multiple threads working in java, but they produce different result everytime I run it. Here is the code:
public class Accum {
private static Accum a = new Accum();
private int counter = 0;
private Accum(){}
public static Accum getAccum(){
return a;
}
public void updateCounter(int add){
counter+=add;
}
public int getCount(){
return counter;
}
}//end of class
public class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<98; x++){
//System.out.println("Counter in TWO "+a.getCount());
a.updateCounter(1000);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("one " + a.getCount());
}
}//end of class
public class ThreadTwo implements Runnable{
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<99; x++){
//System.out.println("counter in Two "+a.getCount());
a.updateCounter(1);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("two "+a.getCount());
}
public class TestThreaad {
public static void main(String[]args){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}end of class
So the expected result would be : one 98098, two 98099, but it turns out that the results are just unpredictable, sometimes it would be 78000 or 81000, I don't know..
but if i add some code to print a line of current value of count, the final result would be correct..
I really have no idea what is going wrong, and even add the keyword synchronized in the ThreadOne and ThreadTwo, run() method, the problem is still there...
I've studied the java for 3 months and this is the most elusive problem I've ever confronted...so thanks in advance for anyone could help me to understand the basic point of multiple threading...
Code is not synchronized. As it is unsynchonized different Thread trying to update counter might be at same time which cause this problem.
If you synchonized updateCounter then access of this method will be in proper.
public synchronized void updateCounter(int add){
counter+=add;
}
In your example, the Accum instance is shared between the threads. Your update process is a typical READ, COMPUTE-UPDATE, WRITE operation sequence. Because the resource is shared and not protected, those three operations (from two threads -- making six operations) can be interleaved in many different ways, causing updates to be lost.
Here is an example ordering of the operations (number indicates thread):
READ #1 -> reads 10
COMPUTE-UPDATE #1 -> computes 1010
READ #2 -> reads 10
WRITE #1 -> writes 1010
COMPUTE-UPDATE #2 -> computes 11
WRITE #2 -> writes 11 (earlier update is lost)
So you see, almost any result is possible. As #SubhrajyotiMajumder notes, you can use synchronized to fix it. But if you do that, maybe threads aren't right for your problem; or alternatively, you need another algorithmic process.
Your code is not synchronized properly.
As an alternative to a synchronized method I would suggest using AtomicInteger to store the variable accessed and modified from different threads.
I am writing a multithreaded parser.
Parser class is as follows.
public class Parser extends HTMLEditorKit.ParserCallback implements Runnable {
private static List<Station> itemList = Collections.synchronizedList(new ArrayList<Item>());
private boolean h2Tag = false;
private int count;
private static int threadCount = 0;
public static List<Item> parse() {
for (int i = 1; i <= 1000; i++) { //1000 of the same type of pages that need to parse
while (threadCount == 20) { //limit the number of simultaneous threads
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Thread thread = new Thread(new Parser());
thread.setName(Integer.toString(i));
threadCount++; //increase the number of working threads
thread.start();
}
return itemList;
}
public void run() {
//Here is a piece of code responsible for creating links based on
//the thread name and passed as a parameter remained i,
//connection, start parsing, etc.
//In general, nothing special. Therefore, I won't paste it here.
threadCount--; //reduce the number of running threads when current stops
}
private static void addItem(Item item) {
itenList.add(item);
}
//This method retrieves the necessary information after the H2 tag is detected
#Override
public void handleText(char[] data, int pos) {
if (h2Tag) {
String itemName = new String(data).trim();
//Item - the item on which we receive information from a Web page
Item item = new Item();
item.setName(itemName);
item.setId(count);
addItem(item);
//Display information about an item in the console
System.out.println(count + " = " + itemName);
}
}
#Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
if (HTML.Tag.H2 == t) {
h2Tag = true;
}
}
#Override
public void handleEndTag(HTML.Tag t, int pos) {
if (HTML.Tag.H2 == t) {
h2Tag = false;
}
}
}
From another class parser runs as follows:
List<Item> list = Parser.parse();
All is good, but there is a problem. At the end of parsing in the final list "List itemList" contains 980 elements onto, instead of 1000. But in the console there is all of 1000 elements (items). That is, some threads for some reason did not call in the handleText method the addItem method.
I already tried to change the type of itemList to ArrayList, CopyOnWriteArrayList, Vector. Makes the method addItem synchronized, changed its call on the synchronized block. All this only changes the number of elements a little, but the final thousand can not be obtained.
I also tried to parse a smaller number of pages (ten). As the result the list is empty, but in the console all 10.
If I remove multi-threading, then everything works fine, but, of course, slowly. That's not good.
If decrease the number of concurrent threads, the number of items in the list is close to the desired 1000, if increase - a little distanced from 1000. That is, I think, there is a struggle for the ability to record to the list. But then why are synchronization not working?
What's the problem?
After your parse() call returns, all of your 1000 Threads have been started, but it is not guaranteed that they are finished. In fact, they aren't that's the problem you see. I would heavily recommend not write this by yourself but use the tools provided for this kind of job by the SDK.
The documentation Thread Pools and the ThreadPoolExecutor are e.g. a good starting point. Again, don't implement this yourself if you are not absolutely sure you have too, because writing such multi-threading code is pure pain.
Your code should look something like this:
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<?>> futures = new ArrayList<Future<?>>(1000);
for (int i = 0; i < 1000; i++) {
futures.add(executor.submit(new Runnable() {...}));
}
for (Future<?> f : futures) {
f.get();
}
There is no problem with the code, it is working as you have coded. the problem is with the last iteration. rest all iterations will work properly, but during the last iteration which is from 980 to 1000, the threads are created, but the main process, does not waits for the other thread to complete, and then return the list. therefore you will be getting some odd number between 980 to 1000, if you are working with 20 threads at a time.
Now you can try adding Thread.wait(50), before returning the list, in that case your main thread will wait, some time, and may be by the time, other threads might finish the processing.
or you can use some syncronization API from java. Instead of Thread.wait(), use CountDownLatch, this will help you to wait for the threads to complete the processing, and then you can create new threads.