Question:
Suppose we pass a ArrayList to Runnable constructor. In the Runnable class we add certain strings to the list. Now we run the Thread from main() and wait for its completion. After the Thread execution is over, is it possible that when we iterate the list in main() we get the strings(values) added to the list by the Runnable class because the reference to the Arraylist is created in Heap.
but when I iterate the list, it is empty. Could anyone explain why the list is empty.
Thanks in Advance:
Vijay K
public class GetListThread implements Runnable{
private List<String> names;
public GetListThread(List<String> names) {
super();
this.names = names;
}
#Override
public void run() {
for(int i=0;i<4;i++){
try {
names.add(ThreadLocalRandom.current().nextInt(1,10) + "A");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println(names);
}
}
public class TestThread {
public static void main(String[] args) {
List<String> names = new ArrayList<String>();
GetListThread g = new GetListThread(names);
Thread t = new Thread(g);
t.start();
System.out.println(t.getState());
for(String s : names){
System.out.println(s);
}
}
}
After the Thread execution is over, is it possible that when we iterate the list in main() we get the strings(values)
Yes, the collection is not thread safe, there is no guarantee you will ever see anything. You might even see null values i.e. where the size is correct but the elements are not.
Could anyone explain why the list is empty.
However in you case, you are not waiting, so there is almost no chance it will have all its elements.
The thread takes time to start, so it is highly unlikely you will even see the first element added.
Related
So the basic idea is this: I have a class called Testing, and in that class, there is an ArrayList of strings. I start a new thread that his sole purpose is to die when the size of the list in my Testing object exceeds the size of 10, while the main program keeps adding Strings to the list. For some reason I am stuck with an infinite loop on the main program, meaning the thread isn't dying.
Here is the code for the thread class
public class TestingThread implements Runnable{
public Testing t;
public TestingThread(Testing t) {
this.t = t;
}
#Override
public void run() {
while(true){
if(t.words.size() > 10) break;
}
}
}
All thats important in the Testing class is that it has a public property List words.
This is what I am trying in main:
public static void main(String[] args) {
Testing t = new Testing();
Thread myThread = new Thread(new TestingThread(t));
myThread.start();
while(true){
if(!myThread.isAlive()) break;
t.words.add("hello");
System.out.println("adding...");
}
System.out.println(ts.words.toString());
// joining the thread to the main thread at the end of the code
try {
myThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("something went wrong");
}
}
The myThread.isAlive() always returns true, so that means that the thread never finished it's while loop, meaning it fails to identify the size of the list have exceeded beyond 10. I can't find a solution for this. any suggestions? should I change my approach on this?
I tried iterating ArrayList object using multi-threading, but sometimes it is giving ConcurrentModificationException and sometimes not? I am unable to understand what is happening here.
I am sharing my code below:
import java.util.ArrayList;
import java.util.Iterator;
public class ConcurrentDemo extends Thread{
static ArrayList l=new ArrayList();
public void run()
{
/*
* try { Thread.sleep(2000); } catch(InterruptedException e) { }
*/
System.out.println("child thread updating list");
l.add("D");
System.out.println(l);
}
public static void main(String args[]) throws InterruptedException
{
l.add("A");
l.add("B");
l.add("c");
ConcurrentDemo c=new ConcurrentDemo();
c.start();
System.out.println(l);
Iterator itr =l.iterator();
while(itr.hasNext())
{
String s1=(String)itr.next();
System.out.println("main thread list:" + s1);
Thread.sleep(3000);
}
System.out.println(l);
}
}
Please see my answer inline in your code:
import java.util.ArrayList;
import java.util.Iterator;
public class ConcurrentDemo extends Thread{
static ArrayList l=new ArrayList();
public void run()
{
System.out.println("child thread updating list");
l.add("D");
System.out.println(l);
}
public static void main(String args[]) throws InterruptedException
{
//----> Main thread starts here
l.add("A");
l.add("B");
l.add("c");
//----> l now contains A,B,C
ConcurrentDemo c=new ConcurrentDemo();
//----> You have started a second thread here
c.start();
//-----> Its not determined, which line will be executed first from now on, as 2 threads are running parallelly, the ConcurrentModificationException most likely occur in cases, when the "l.add("D");" called within the "run();" method AFTER the Iterator has been created.
System.out.println(l);
Iterator itr =l.iterator();
while(itr.hasNext())
{
String s1=(String)itr.next();
System.out.println("main thread list:" + s1);
Thread.sleep(3000);
}
System.out.println(l);
}
}
Please note regarding to interators, that the behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling the appropriate method on the Iterator interface.Reference
Instead of randomly failing when you do this, the collection is nice
enough to keep track of how many times it's been modified, and throw
ConcurrentModificationException when it detects concurrent
modification. Reference
If you plan to modify the underlying collection of an iterator by adding new elements, consider using the ListIterator
Example with your code:
static ArrayList l=new ArrayList();
ListIterator listItr =l.listIterator();
listItr.add(e);
For further informations, check out this Java Concurrency and Multithreading tutorial.
EDIT:
As it might be hard to notice, I am highlighting the most important inline comment within the code above:
After you have called c.start(); its not determined, which line will be executed first, as 2 threads are running parallelly, the ConcurrentModificationException most likely occur in cases, when the l.add("D"); called within the run(); method after the Iterator has been created.
So I have two threads running where one of them is supposed to get information from the user and the other thread is suppose to work with information supplied by users as follows:
public class UserRequest implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
String request;
Scanner input = new Scanner(System.in);
while(true)
{
System.out.println("Please enter request:");
request = input.nextLine();
try
{
//do something
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
And second thread:
public class Poller implements Runnable {
ArrayList<String> colors = new ArrayList<String>();
public void poll()
{
for(String color : colors)
{
if(color == "")
{
//do work
}
else
{
//do work
}
}
}
#Override
public void run() {
colors.add("Violet");
colors.add("Green");
colors.add("Yellow");
colors.add("Orange");
while(true)
poll();
}
}
What I would like to do is take whatever input the user entered inside the UserRequest object and push into the ArrayList in Poller object so it can "work" on the new value as well. I have looked at some thing like BlockingQueue but I don't want either Thread to wait for the other since they have other tasks they need to accomplish in addition to this sharing of data. How can I go about doing this ?
Since you've used the verb 'push' and 'poll', it seems you are looking for a Queue not a List.
Therefore, I think you're looking for the ConcurrentLinkedQueue, documented here.
It allows you to have your UserRequest objects feed it and your Poller objects to consume it.
Though it seems your Poller objects will have quite a high CPU consuption because of the open while not having any wait:
public class Poller implements Runnable {
Queue<String> colors = new ConcurrentLinkedQueue<String>();
public void poll() {
while(this.colors.isEmpty()){
Thread.currentThread().wait();
}
String color = this.colors.poll();
while(color != null) {
if(color == "") {
//do work
} else {
//do work
}
color = this.colors.poll();
}
}
#Override
public void run() {
colors.offer("Violet");
colors.offer("Green");
colors.offer("Yellow");
colors.offer("Orange");
while(true) {
this.poll();
}
}
}
this code needs some changes to run but it contains pretty much everything you need.
What it does is very simple: It keeps polling until there are no elements left.
Once that happens, the Poller object asks it's current Thread to sleep, since there's no point for it to run without elements in the Queue.
public class UserRequest implements Runnable {
#Override
public void run() {
String request;
Scanner input = new Scanner(System.in);
while(true) {
System.out.println("Please enter request:");
request = input.nextLine();
try {
//do something
} catch(IOException e) {
e.printStackTrace();
} finally {
this.notifyAll(); // Notifies all sleeping threads to wake up
}
}
}
If you notice, I've only added a notifyAll call to your UserRequest class. Why? Very simple: notifyAll wakes all waiting Threads which is exactly what all Pollers without elements are doing.
Once it's called, the Pollers will wake, check if their color Queue has elements and work with them. If the Queue has no elements, they will sleep again until a UserRequest wakes them up again and so on and so forth.
There are two ways to solve this problem:
1) It's using thread safe collection, like ConccurentLinkedQueue for logic with producer-consumer, jobs consuming or etc. If you want to use the class that implements List interface (and as a consequence you can take methods same to usual ArrayList), you must look to the side of CopyOnWriteArrayList, but note that this class uses blocking synchronization.
2) Another approach is using built-in java synchronization tools, for example
Semaphore
CyclicBarrier
CountDownLatch
Locks
Phaser
Usual wait/notify mechanism
For more details, you must read the specification. Let's consider an example of using Semaphore:
private final Semaphore semaphore = new Semaphore(2, true);
public void appendToList() throws InterruptedException {
available.acquire();
arrayList.add(.....); //put here what u need
}
public void putItem(Object x) {
if (someLogicHere(x)) //semaphore releases counter in this place
available.release();
}
Of course, you can combine usage all of them, e.g. you can use a few semaphores simultaneously, or use diff tools.
"but I don't want either Thread to wait for the other since they have other tasks they need to accomplish in addition to this sharing of data."
There's no way to accomplish this. Any proper threading of the class will always suffer from the problem that you will need to have one thread wait while the other does something. The point though is you want to minimize that. You want to only cause the thread to stall very briefly and rarely and only in those cases where not doing so will cause it to fault. You can use one of the synchronized data structures or you can just write a little bit of synchronization code yourself.
The only object in question is the arraylist, and you want the absolute minimum amount of stall on either thread. So you would want to synchronize it based on the object of the arraylist itself. So just write a couple little synchronization blocks around the points where you access the arraylist object.
public class Poller implements Runnable {
ArrayList<String> colors;
public Poller(ArrayList<String> colors) {
this.colors = colors;
//pass in colors object, if modified from the scanner side it must synchronize the block around the colors object too.
}
public void doWork(String color) {
//do work
}
public void addColor(String color) {
synchronized (colors) {
colors.add(color);
}
}
#Override
public void run() {
while (!Thread.interrupted())
if (!colors.isEmpty()) {
String color;
synchronized (colors) {
color = colors.remove(0);
}
doWork(color); //work done outside synch
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The point is just never be removing or adding things to the list at the same time. You cannot loop over the list as a whole because if the work is done in-loop it's a problem and the size of the array might change so you don't know how bit it is. But, you can use an ArrayList for this, just synchronize the blocks of code where you change the datastructure and get the string out of that synchronized block and then do work on it. This way the only stall is the brief instant one thread is reading or writing and the other one needs to. Both of which are very fast operations.
If you want access new value entered by the user from poller object then:
As objects are stored in heap , instead of creating a new instance of arrayList in the Poller class you could just send a reference of list object from the UserRequest.So that when yu change add new value to arrayList in userRequest it will be reflected in arrayList being used by Poller.
For Example, You can do it this way:
public class UserRequest implements Runnable {
private ArrayList<String> arrayList = new ArrayList<String>();
#Override
public void run() {
// TODO Auto-generated method stub
String request;
Scanner input = new Scanner(System.in);
while(true)
{
System.out.println("Please enter request:");
request = input.nextLine();
try
{
Poller poller = new Poller(arrayList);
Thread t = new Thread(poller);
t.start();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
You can change your Poller class like this:
public class Poller implements Runnable {
private ArrayList arrayList = null;
Poller(ArrayList<String> arrayList){
this.arrayList = arrayList;
}
public void poll()
{
for(String color : arrayList)
{
if(color == "")
{
//do work
}
else
{
//do work
}
}
}
#Override
public void run() {
while(true){
poll();
}
}
But instead of calling pool in a infinity loop you should add a listener to your arrayList so that you call poll() only when a new value has been added to the List.
You can check out this link to know more about adding listener to a ArrayList: https://stackoverflow.com/a/16529462/7083385
You can use a queue. A queue has its own poll method. You could make it static but i doubt that is the best approach. Generally I use spring to instantiate the queue in some kind of wrapper class but it doesnt look like you are taking that route.
I have a static function like:
public static void foo()
{
//code follows
System.out.println(Thread.currentThread().getName());
//code follows
}
and multiple threads are calling this function concurrently. I have set the names of threads using
Thread.setName(String)
When i execute the code, the print statement will print the name of only one thread. How can i identify the names of all the threads currently executing the foo() function?
EDIT:
public class FooThread extends Thread
{
public FooThread(String name)
{
this.setName(name);
}
#Override public void run()
{
//do something
//do something
Main.foo();
}
}
//Main Class
public class Main
{
public static void main(String[] args)
{
for(int i=0;i<6;++i)
{
new FooThread("Thread"+i).start();
}
}
public static void foo()
{
//do something
while(true)
{
//do something
System.out.println(Thread.currentThread().getName());
}
}
}
You're already showing the name of the Thread that is calling your code. Code that proves this:
public class Foo2 {
public static synchronized void foo() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
int maxCount = 10;
for (int i = 0; i < maxCount; i++) {
Thread thread = new Thread(new Runnable() {
public void run() {
foo();
}
});
thread.setName("Thread " + i);
thread.start();
long sleepTime = 1000;;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
}
}
Return:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
Your problem lies in code not shown.
Either your method is being called by one and only one thread, or
Or you're giving all your threads the same name.
Again, for a complete solution as to what is actually wrong with your current set up, create and post an sscce similar to what I've posted above. For all we know you could be calling run() on your Threads, and until we can see and reproduce your problem, I don't think that we'll be able to fully understand it.
EDIT
Regarding your SSCCE: Compare the results of the two methods below, foo1() and foo2()
class FooThread extends Thread {
public FooThread(String name) {
this.setName(name);
}
#Override
public void run() {
// do something
// do something
Main.foo1(); // !! Swap comments
// Main.foo2(); // !! Swap comments
}
}
// Main Class
public class Main {
private static final long SLEEP_TIME = 4;
public static void main(String[] args) {
for (int i = 0; i < 6; ++i) {
new FooThread("Thread" + i).start();
}
}
public static void foo1() {
// do something
while (true) {
// do something
synchronized (Main.class) {
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {}
}
}
public static void foo2() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
}
If your while loop isn't so tight, but yields the CPU with say a short Thread.sleep, you'll see more of the different threads sharing foo in closer proximity.
But again, your code also proves that your Thread names *are8 being displayed, but that you're only seeing one name likely because that thread is hogging the CPU.
Another option is to get all the Thread stacks and look for all the threads in the foo() This has the benefit of no overhead or extra code, except to capture the information you want.
BTW: Can you make it clearer why do you need this information as I suspect there is a better way to do what you really want?
If you only want to get the count of threads, use a thread-safe counter to store number of threads. Increase the counter when foo() begins, and decrease the counter when foo() exits.
If you need to get the names, use a hash set (or list if there are duplicates of thread names) to store the names: Add the name when foo() begins, and remove the name when foo() exits. Make sure the access to hash set is thread safe. You also need another method to print out the content of the hash set, so you can call it any time to see what are the name of threads executing foo().
You can put the name into a list when the method starts (in a synchronized block) and remove it at the end again.
List allTheNames = Collections.synchronizedList(new ArrayList<String>());
public void foo() {
allTheNames.add(Thread.currentThread().getName());
// now allTheNames contains all the names of all threads currently in this method.
System.out.println(allTheNames.toString());
allTheNames.remove(Thread.currentThread().getName());
}
Of course, if you change the name of the thread in the meantime that wont work, but why would you do so?
You could also store the Thread itself if you need other informations that the name.
I have searched a lot but not able to find particular solution. There are also some question regarding this on stackoverflow but i am not able to find satisfactory answer so i am asking it again.
I have a class as follow in java . I know how to use threads in java.
//please do not consider syntax if there is printing mistake, as i am typing code just for showing the concept in my mind
public class myclass{
private List<String> mylist=new ArrayList<String>();
public addString(String str){
//code to add string in list
}
public deleteString(String str){//or passing an index to delete
//code to delete string in list
}
}
now i want to do these two operations simultaneously. for that i have created two thread class one performs addString() logic in run and another perform deleteString() logic.i am passing mylist in the constructor of each thread but how can i return an object after performing addition and deletion to mylist?
Before i was thinking that "If i am passing the mylist in constructor of thread it passes the address of the mylist to thread and thread performs operations on it that changes refer to mylist object" But it is not like that as the changes are not reflacted to mylist object . can any one elaborate this?
what is the best way to achieve this?
the requirement is like that if a thread is inserting an element at last another thread should be able to delete some element at other index say 2nd simultaneously.
EDIT
i have done it as follow: thanx to Enno Shioji
public class myClass {
private List<String> mylist = Collections.synchronizedList(new ArrayList<String>());
public myClass(){
mylist.add("abc");
mylist.add("def");
mylist.add("ghi");
mylist.add("jkl");
}
public void addString(String str) {
mylist.add(str);
}
public void displayValues() {
for (int i = 0; i < mylist.size(); i++) {
System.out.println("value is " + mylist.get(i) + "at " + i);
}
}
public void deleteString(int i) {
mylist.remove(i);
}
}
class addThread {
public static void main(String a[]) {
final myClass mine = new myClass();
Thread t1 = new Thread() {
#Override
public void run() {
mine.displayValues();
mine.addString("aaa");
mine.displayValues();
}
};
Thread t2 = new Thread() {
public void run() {
mine.displayValues();
mine.deleteString(1);
mine.displayValues();
}
};
t1.start();
t2.start();
}
}
is there any other way to do so?
Use Synchronized List , It would be thread safe
Use Collection.synchronizedList(yourPlainList)
Threads and object instance are different concepts. If you want to share data among threads, you need to access a single object instance from two threads. In this case, you should do something like this.
public class MyClass{
private final List<String> mylist = new ArrayList<String>();
public synchronized void addString(String str){
//code to add string in list
}
public synchronized void deleteString(String str){
//or passing an index to delete
//code to delete string in list
}
}
and then
final MyClass mine = new MyClass();
Thread t1 = new Thread(){
public void run(){
mine.addString("aaa");
}
}();
Thread t2 = new Thread(){
public void run(){
mine.deleteString("bbb");
}
}();
t1.start();
t2.start();
Note how you are referring to the same object instance (mine) from both threads. Also note that I added the synchronized keyword to make MyClass thread-safe. This forces all operations to be done sequentially rather than truly "simultaneously". If you want true simultaneous operations on the collection, you will need to use concurrent data structures like a Skip List and get rid of synchronized keyword.