I have two threads. One thread has an instance of myObjectManager. myObjectManager has a list of objects, and a method for retrieving an object( public myObjectClass getObjectById(int ID) )
I need the first thread to render an object in myObjectManagers list of objects, and the second thread to perform game logic and move it around etc.
This is what I tried
//thread 1:
m = myObjectManager.getObjectById(100);
m.render();
//thread 2:
m = myObjectManager.getObjectById(100);
m.rotate( m.getRotation() + 5 ); //increment rotation value
However, it seems that thread 1 has an instance of the object without the updated rotation. When I run it, the rendered object doesn't rotate, but when I make the second thread print out the rotation value it is rotated.
In C++ I would just make the function getObjectById() return a pointer to an instance of myObjectClass, but I'm not sure what exactly java does when I say "return myInstance;"
How would I do something similar in java?
Sorry, I'm new to this language!
In Java, all Object variables are "pointers" (or "references", as people typically say). The problem must be elsewhere. My guess is that thread 1 has already rendered the object before thread 2 has even modified it.
Edit: Another theory: subsequent render() operations don't actually change the screen display. The rotation value is updated just fine - but it doesn't reflect to the display.
The references (pointers) are alright but in Java each thread is allowed to make local copies of objects (think of it like a cache) they're working with and unless they are synchronized in some way, changes made by one thread may not be visible to the other.
This tutorial will hopefully help.
You have 2 potential problems, both of which have been stated here in different answers.
You give no indication as to any
control of ordering of your thread
operations. Therefore the render
may be occurring before the rotation
update. This assumes that the the
classes involved are in fact
threadsafe and will behave as
expected.
If the classes are not
threadsafe (i.e. synchronized in
some way), then the updates to the
rotation thread may never be seen in
the rendering thread.
To know for sure we would have to see the source for the m class. Also, you may have issues with the getObjectById() as well if it is not threadsafe either.
Try marking your rotation variable in the object as volatile
All objects in Java are passed by reference.
It is impossible to write code that does what you're trying not to do.
Your first thread is probably running before the second thread.
All object references in Java, like your m variable, are in fact pointers.
So in your example, both m variables point to the same object.
Related
I was monitoring my application with the task manager and saw that the RAM usage is constantly going up.
I quickly noticed that I initialized a new variable in every iteration of the for loop:
for (int i = 0; i < List.size(); i++)
{
data = List.get(i); //This is already declared outside
CustomThread thread2= new CustomThread(data);
executor.execute(thread2);
}
Now, does declaring CustomThread thread2 outside of the loop be of any benefit?
Would the execute(thread2) be still connected to the original object when accessing it later? Or maybe, the object is overwritten, and gets overwritten for every execute, causing it to do the same exact thing (the behaviour is based on the data) ?
EDIT:
I roughly need 200 threads (they are not too heavy but they do connect to a website), also, the snippet and the code before it, is a runnable that gets called every 20 seconds (so yeah, I'd create roughly 600 threads per minute)
Where you declare the variable doesn't matter except for scoping; where you create the object matters, because presumably you need to call executor.execute with different CustomThread objects on each call. (If you don't, then yes, obviously, create a single object outside the loop and reuse it.)
The way you have it is how I'd write it, except:
You might just do away with the variable entirely if you don't need it for anything else:
executor.execute(new CustomThread(data));
I might declare data within the loop body unless you have a good reason for declaring it outside.
...since there's no benefit to broadening the scope of that thread2 variable if you don't need it outside the loop.
No.
When you use the keyword new you create a new memory address, so you will be always creating a new thread for each iteration.
It is rather clear that the actual code doesn't cause directly the memory consumption issue.
data is an element of the List. Assigning it a temporary variable doesn't create a new object. It just creates a "link" to the actual object.
Your problem is probably related to what you perform in your threads.
Creating and running hundreds of threads concurrently that create objects may finally created a number very important of objects.
Rather than guessing, use a monitoring tool as JVisualVM and you should easily find the culprit.
Currently I have an object which I receive from a server, this contains two co-ordinates to be drawn to a canvas, which I can currently do in another class with hard coded co-ordinates.
My problem is that I cannot work out how to send the object (which is within a thread) to the second drawing class to be drawn.
An object is never within a thread. The best you can hope for is that only one thread references the object, and constant vigilance is required to keep it that way. Objects accessed by only one thread do not require anywhere near the thought and care that objects accessed by more than one thread do. But it's real hard to keep objects on one thread, and you can't do that here in any case.
Your object from the server can be referenced from a public, static field in any class, and so be made available anywhere in your program (and to any thread). There has to be a more elegant way to make it available where needed--to encapsulate it properly--but this will do as a fallback solution.
Then you have to take care of multi-threaded access. It sounds like your object can be made immutable. This just means that once you make it "public" by assigning it to it's referencing field, you never change it again (even if it is theoretically possible to do so). This makes things simpler and faster. Create your received object and, when it is fully assembled, place it in its field. Make sure that field is marked volatile so any changes will be immediately seen elsewhere.
Now your drawing class merely needs to look at the object when it needs it. However, before using it you want to copy the object to a local variable. The local variable will continue to point to the same object throughout the drawing process. The volatile field may change at any instant, continually refering to new or different objects. Using the local variable, your X and Y coordinates will always be consistent, if out-of-date. (Everything's a bit out-of-date in a multi-threading system.) If you used the field, you could get the X from one object sent from the server and the Y from another. (The real fun with multi-threading comes when X * X, where the X is an integer, gives a value of 35--same X from two different objects. That and when if (aA != null) aA.doSomething() throws a null pointer exception. Using local variables prevents all this.)
For now I think you can avoid synchronization and wait states. You might want to make your coordinate object truly immutable (with final fields) so other programmers (or even you after 6 months of doing other work) don't change the code to modify the object on the fly. (If they/you do, they/you will need synchronization.)
A Handler is one good way to transfer messages and data from a communications worker thread to the UI thread.
It would be more ideal if you included the basic outline of your code in your question. However, I would assume that what you basically have is a custom View (which you refer to as your "drawing class") which forms part of an overall layout that's set as the content view for your Activity. I then assume you have a communications worker thread, which might be contained within that same Activity class (or perhaps in a separate Service class - but for now I'll assume the simplest case). For your communications worker thread to update your View, the View needs to be updated on the UI thread. Therefore you would instantiate a Handler object that will run on the UI thread (perhaps in onCreate()) which updates the View based on the content of messages. Your worker thread then sends messages to that Handler.
I have a instance of a object which performs very complex operation.
So in the first case I create an instance and save it it my own custom cache.
From next times whatever thread comes if he finds that a ready made object is already present in the cache they take it from the cache so as to be good in performance wise.
I was worried about what if two threads have the same instance. IS there a chance that the two threads can corrupt each other.
Map<String, SoftReference<CacheEntry<ClassA>>> AInstances= Collections.synchronizedMap(new HashMap<String, SoftReference<CacheEntry<ClassA>>>());
There are many possible solutions:
Use an existing caching solution like EHcache
Use the Spring framework which got an easy way to cache results of a method with a simple #Cacheable annotation
Use one of the synchronized maps like ConcurrentHashMap
If you know all keys in advance, you can use a lazy init code. Note that everything in this code is there for a reason; change anything in get() and it will break eventually (eventually == "your unit tests will work and it will break after running one year in production without any problem whatsoever").
ConcurrentHashMap is most simple to set up but it has simple way to say "initialize the value of a key once".
Don't try to implement the caching by yourself; multithreading in Java has become a very complex area with Java 5 and the advent of multi-core CPUs and memory barriers.
[EDIT] yes, this might happen even though the map is synchronized. Example:
SoftReference<...> value = cache.get( key );
if( value == null ) {
value = computeNewValue( key );
cache.put( key, value );
}
If two threads run this code at the same time, computeNewValue() will be called twice. The method calls get() and put() are safe - several threads can try to put at the same time and nothing bad will happen, but that doesn't protect you from problems which arise when you call several methods in succession and the state of the map must not change between them.
Assuming you are talking about singletons, simply use the "demand on initialization holder idiom" to make sure your "check" works across all JVM's. This will also make sure all threads which are requesting the same object concurrently wait till the initialization is over and be given back only valid object instance.
Here I'm assuming you want a single instance of the object. If not, you might want to post some more code.
Ok If I understand your problem correctly, you are worried that 2 objects changing the state of the shared object will corrupt each other.
The short answer is yes they will.
If the object is expensive in creation but is needed in a read only manner. I suggest you make it immutable, this way you get the benefit of it being fast in access and at the same time thread safe.
If the state should be writable but you don't actually need threads to see each others updates. You can simply load the object once in an immutable cache and just return copies to anyone who asks for the object.
Finally if your object needs to be writable and shared (for other reasons than it just being expensive to create). Then my friend you need to handle thread safety, I don't know your case but you should take a look at the synchronized keyword, Locks and java 5 concurrency features, Atomic types. I am sure one of them will satisfy your need and I sincerely wish that your case is one of the first 2 :)
If you only have a single instance of the Object, have a quick look at:
Thread-safe cache of one object in java
Other wise I can't recommend the google guava library enough, in particular look at the MapMaker class.
Project background aside, I've implemented a table of custom JComboBoxes. Each row of ComboBoxes is exclusive: while each ComboBox has its own model (to allow different selections), each choice can only be selected once per row. This is done by adding a tag to the front of an item when selected and removing it again when deselected. If a user tries to select a tagged item, nothing happens.
However, this only works when using a Vector as the backing for the list of options. I can get the Vector of strings, use either set() or setElementAt(), and boom presto it works.
With an ArrayList instead of a Vector, however, this doesn't work at all. I was under the impression that ArrayLists functioned similarly in that I can retrieve an anonymous ArrayList, change its contents, and all other objects relying on the contents of that ArrayList will update accordingly, just like the Vector implementation does.
I was hoping someone could tell me why this is different, as both Vector and ArrayList implement List and supposedly should have similar behavior.
EDIT:
Thanks for the prompt responses! All answers refer to synchronization disparities between ArrayList and Vector. However, my project does not explicitly create new threads. Is it possible that this is a synchronization issue between my data and the Swing thread? I'm not good enough with threads to know...
2nd EDIT:
Thanks again everybody! The synchronization between data and Swing answers my question readily enough, though I'd still be interested in more details if there's more to it.
I suspect the difference is due to Vector being thread-safe and ArrayList not. This affects the visibility of changes to its elements to different threads. When you change an element in a Vector, the change becomes visible to other threads instantly. (This is because its methods are synchronized using locks, which create a memory barrier, effectively synchronizing the current state of the thread's memory - including the latest changes in it - with that of other threads.) However, with ArrayList such synchronization does not automatically happen, thus the changes made by one thread may become visible to other threads only later (and in arbitrary order), or not at all.
Since Swing is inherently multithreadedd, you need to ensure that data changes are visible between different (worker, UI) threads.
Vector is synchronized. It uses the synchronized keyword to ensure that all threads that access it see a consistent result. ArrayList is not synchronized. When one thread sets an element of an ArrayList there is no guarantee that another thread will see the update.
Access to Vector elements are synchronized, whereas its not for an ArrayList. If you have different threads accessing and modifying the lists, you will see different behavior between the two.
I don't have time to test this code, and your code sample is still really light (a nice fully functional sample would be more helpful - I don't want to write a full app to test this) but I'm willing to bet that if you wrapped your call to 'setSelectDeselect' (as shown in your pastebin) like this then ArrayList would work as well as Vector:
Runnable selectRunnable = new Runnable()
{
public void run()
{
setSelectDeselect(cat, itemName, selected);
}
};
SwingUtilities.invokeLater(selectRunnable);
You're updating your ArrayList in the middle of event processing. The above code will defer the update until after the event is complete. I suspect there's something else at play here that would be apparent from reviewing the rest of your code.
I have a kind of async task managing class, which has an array like this:
public static int[][][] tasks;
Mostly I access the cells like this:
synchronized(tasks[A][B]) {
// Doing something with tasks[A][B][0]
}
My question is, if I do this:
synchronized(tasks[A]) {
// ...
}
will it also block threads trying to enter synchronized(tasks[A][B])?
In other words, does a synchronized access to an array also synchronizes the accsess to it's cells?
If not, how to I block the WHOLE array of tasks[A] for my thread?
Edit: the answer is NO. When someone is in a synchronized block on tasks[A] someone else can simultaniously be in a synchronized block on tasks[A][B] for example - because it's a different object. So when talking about accessing objects from one place at a time, arrays are no different: to touch object X from one place at a time you need to surround it by synchronized(X) EVERYWHERE you touch it.
No. Each array is an Object (with a monitor) unto itself; and the array tasks[A] is a distinct object from the array tasks[A][B]. The solution, if you want to synchronize all accesses to "sub" arrays of tasks[A] is simply that you must do synchronized (tasks[A]). If all accesses into the descendant objects (say, tasks[A][B]) do this, then any further synchronization is redundant.'
It appears your underlying question is actually something like "how can I safely modify the structure as well as the contents of a data structure while retaining the best concurrency possible?" If you augment your question a bit more about the problem space, we might be able to delve deeper. A three-dimensional array may not be the best solution.
int[][][] is an array of arrays of integer arrays, so your synchronized(tasks[A][B]) is synchronizing on the lowest level object, an array of integers, blocking other synchronized access to that same array.
synchronized(tasks[A]) on the other hand is synchronizing the object at the next level up - an array of integer arrays. This prevents synchronized access to that array, which means, in practice that any other code which uses synchronized(tasks[A]) will be blocked - which seems to be what you want, so long as all your acccesses to tasks synchronizes at the same level.
Note that synchronize does not lock anything! However, if two threads attempt to synchronize on the same object, one will have to wait.
It doesn't matter that you then work on another object (your array of integers).
I'm afraid I'm saying that andersoj's answer is misleading. You're doing the right thing.
Whenever I see code that grabs lots of different mutexes or monitors, my first reaction is to worry about deadlock; in your current code, do you ever lock multiple monitors in the same thread? If so, do you ensure that they are locked in a canonical ordering each time?
It would probably help if you could explain what you are trying to accomplish and how your are using / modifying this tasks array. There are surprising (or perhaps unsurprising) number of cases where the utilities in java.util.concurrent are sufficient, and using individual monitors isn't necessary. Of course, it all depends on what exactlly you are trying to do. Also, if the reason you are trying to grab so many different locks is because you are reading them very frequently, it is possible that using a single read-write lock for the entire 3d jagged-array object might be sufficient for your needs.