I am creating a small tank game using java. In that game, lifepacks and coin piles are generated at a random place on the game grid time to time. They both have a limited lifetime and after lifetime expires they are vanished from the field. When they visible on the grid, any tank can acquire them before vanish. And I want to keep the list of lifepack objects and coinpile objects in an ArrayList in order to access them by the game AI algorithm. I hope to implement the above concept as follows using simple java knowledge.
Following is my LifePack class.CoinPile class behaves in a similar manner:
public class LifePack extends Thread{
public int healthBonus;
public int lifetime;
public String type;
public Point location;
public boolean visible;
public LifePack(int x,int y,int lifetime){
location=new Point(x, y);
this.lifetime=lifetime;
this.type="health_pack";
this.visible=true;
this.start();
}
public void run(){
while(true){
if(this.lifetime>0){
try{
Thread.sleep(1);
if(lifetime%1000==0){
System.out.println("Life pack "+this.getId()+" will be disappeared in "+this.lifetime/1000+" s");
}
this.lifetime--;
}
catch(Exception ex){
ex.printStackTrace();
}
}
else{
this.visible=false;
this.interrupt();
break;
}
}
System.out.println("Life pack visibility = "+this.visible);
}
}
I want to add the newly created LifePack Objects into an arraylist as follows:
public ArrayList<LifePack> lifePacks;
lifePacks = new ArrayList<LifePack>();
lifePacks.add(new LifePack(x, y, lifeTime));
Each time a new lifepack is created I add that lifepack object into the arraylist above. Once the lifepack's lifetime expires, I want to set the 'visible' boolean variable in the above class to 'false' so that I can check that variable for other purposes.
But I don't get my desired output. Can I add running thread objects into an arraylist as above and keep the thread state running or Will I have to move to a different implementation? Please somebody help me to clear this out if there is a solution.
Thank you.
I agree with dirkk that you will spin up too many threads. But to answer your question maybe you should consider using AtomicBoolean for visible.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicBoolean.html
From what I see, one Thread checks if some entry in a list is false, some other thread sets it to false, this needs to be thread safe.
You could do that by synchronizing the list itself during the update operation
synchronized(list){
//update the needed entry to false
}
As already pointed out, creating threads is a bad idea. In particular, once your application comes to a point at which very many lifepacks exist. Also note that starting a thread in a constructor is very bad practice. If you want to use plain threads, implementing a runnable (java.lang.Runnable) is advisable.
In general, however, I would strongly encourage you to use the Java concurrency abstractions available in the java.util.concurrent package: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html Using an ExecutorService to run callables (java.util.concurrent.Callable) allows you to vary the number of threads quite easily.
I would also question your idea of storing all the lifepacks in the same collection and assigning each of them a state (visiblity). Spontaneously, I could think of the following scenario: once the game runs for quite some time, you will end up with a large collection of lifepacks, most of which are not used anymore. Therefore, you might want to think about having different collections for the different states a lifepack can be in. This would also make throwing away object quite easy (without traversing a collection). Aussuming that those collections would be accessed by more than one thread, you'd want them to be thread-safe. For that, you'll find various types of collections in the java.util.concurrent package as well.
Related
Is something like the following 'safe' in Java, and why?
public final class Utility {
private Utility() {}
private static Method sFooMethod = null;
public static void callFoo(SomeThing thing) {
try {
if(sFooMethod == null)
sFooMethod = SomeThing.class.getMethod("foo");
sFooMethod.invoke(thing);
} catch(Exception e) {} // Just for simplicity here
}
}
My rationale would be that even if another thread writes to sFooMethod in the background and the current thread sees it suddenly somewhere during execution of callFoo(), it would still just result in the same old reflective invoke of thing.foo()?
Extra question: In what ways does the following approach differ (positive/negative) from the above? Would it be preferred?
public final class Utility {
private Utility() {}
private static final Method sFooMethod;
static {
try {
sFooMethod = SomeThing.class.getMethod("foo");
} catch(Exception e) {}
}
public static void callFoo(SomeThing thing) {
try {
if(sFooMethod != null)
sFooMethod.invoke(thing);
} catch(Exception e) {}
}
}
Background update from comment:
I am writing an Android app and I need to call a method that was private until API 29, when it was made public without being changed. In an alpha release (can't use this yet) of the AndroidX core library Google provides a HandlerCompat method that uses reflection to call the private method if it is not public. So I copied Google's method into my own HandlerCompatP class for now, but I noticed that if I call it 1000 times, then the reflective lookup will occur 1000 times (I couldn't see any caching). So that got me thinking about whether there is a good way to perform the reflection once only, and only if needed.
"Don't use reflection" is not an answer here as in this case it is required, and Google themselves intended for it to happen in their compatibility library. My question is also not whether using reflection is safe and/or good practice, I'm well aware it's not good in general, but instead whether given that I am using reflection, which method would be safe/better.
The key to avoiding memory consistency errors is understanding the happens-before relationship. This relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement.
Java language specification states following:
17.4.5. Happens-before Order
Two actions can be ordered by a happens-before relationship. If one
action happens-before another, then the first is visible to and
ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x
happens-before y.
If x and y are actions of the same thread and x comes before y in
program order, then hb(x, y).
As, in your case, writing to and then reading from the static field are happening in same tread. So the `happens before' relation is established. So the read operation will always see effects of the write operation.
Also, all threads are going to write same data. At worse, all eligible threads will write to the variable same time. The variable will have reference to the object that got assigned last and rest of the dereferenced objects will be garbage collected.
There won't be many threads in your App which will enter the same method at once, which will cause significant performance hit due to lot of object creation. But if you want to set the variable only once then second approach is better. As static blocks are thread safe.
Is something like the following 'safe' in Java, and why?
No I would not recommend using reflections, unless you have to.
Most of the time developers design their classes in a way, so that access to a hidden field or method is never required. There will most likely be a better way to access the hidden content.
Especially hidden fields and methods could change their name, when the library they are contained in is updated. So your code could just stop working suddenly and you would not know why, since the compiler would not output any errors.
It is also faster to directly access a method or field then through reflections, because the reflections first need to search for it and the direct access don't
So don't use reflections if you don't have to
I'm not sure what your goal is -- there is probably a better way to do what you're trying to do.
The second approach, with a static initializer, is preferable because your first implementation has a race condition.
I have the following Java code:
private Object guiUpdateLock = new Object();
public void updateLinkBar(SortedSet<Arbitrage> arbitrages) {
synchronized (guiUpdateLock) {
System.out.println("start");
for (Arbitrage arbitrage : arbitrages) {
//do some GUI stuff
}
System.out.println("end");
}
}
updateLinkBar() is called from many threads, and occasionally I get java.util.ConcurrentModificationException in "for" cycle.
But I can't understand why since I'm making a lock on object which obviously doesn't work because I can see two "start" in a row in the output.
Thank you in advance.
Locks must protect objects and not segments of code.
In your case you accept an arbitrary collection, acquire your private lock, and operate on the collection. Meanwhile the rest of your code may, in other threads, do whatever it wants with the collection and it doesn't have to contend for your private lock to do it.
You must significantly redesign your code such that all access to the collection in question is covered by the same lock.
Without your complete code I have to resort to guessing, but the most likely case is that the two threads are using different guiUpdateLog-Objects to synchronize on. My further guessing would be that they are using different instances of the class that contains the guiUpdateLock - and since it is not static there will be different Object-instances as well.
I am new to Java, and have come across a problem when trying to implement a simple game.
The premise of the game currently is, a timer is used to add a car, and also more frequently to update the movement of the car. A car can be selected by touch, and directed by drawing it's path. The update function will move the car along the path.
Now, the game crashes with an IndexOutOfBoundsException, and I am almost certain this is because occasionally, when a car is reselected, the current path is wiped and it allows a new path to be drawn. The path is stored as a LinkedList, and cleared when the car is touched.
I imagine if the path is cleared via a touch event, whilst the timer thread is updating the cars movement along the path, this is where the error occurs (There are also similar other issues that could arise with two threads accessing this one list.
My question, in Java, what would be the best way of dealing with this? Are there specific types of lists I should be using rather than LinkedList, or are there objects such as a Mutex in c++, where I can protect this list whilst working with it?
In Java, this is usually accomplished using synchronization
A small example might look something like this:
LinkedList list = //Get/build your list
public void doStuffToList()
{
synchronized(list)
{
//Do things to the list
}
}
public void clearList()
{
synchronized(list)
{
list.clear();
}
}
This code won't let the clear operation be performed if there's another thread currently operating on the list at that time. Note that this will cause blocking, so be careful for deadlocks.
Alternatively, if your List is a class that you've built yourself, it probably makes sense to make the data structure thread safe itself:
public class SynchroLinkedList
{
//Implementation details
public synchronized void doThingsToList()
{
//Implementation
}
public synchronized void clearList()
{
//Implementation
}
}
These two approaches would effectively work the same way, but with the second one your thread safety is abstracted into the datatype, which is nice because you don't have to worry about thread safety all over the place when you're using the list.
Instead of recreating your own thread safe list implementation, you have several built-in options, essentially:
use a synchronized list:
List list = Collections.synchronizedList(new LinkedList());
Note that you need to synchronize on the list (synchronized(list) { }) for iterations and other combined operations that need to be atomic)
use a thread safe collection, for example a CopyOnWriteArrayList or a ConcurrenLinkedQueue, which could be a good alternative if you don't need to access items in the middle of the list, but only need to add an iterate.
Note that a CopyOnWriteArrayList might have a performance penalty depending on your use case, especially if you regularly add items (i.e. every few microseconds) and the list can become big.
class A implements Callable{
List result // want to share this List amongst thread and their function call
public Search call() {
List<Job> Jobs = api. Jobs(a,b,c); // Multiple threads
}
}
class API{
public void jobs(a,b,c){
// want to access the A.Result and populate the result
}
}
How can i share an array List amogst all threds, I dont want to use the Static ,
as it will keep accumilating the result every time it runs ,
Is Thread Local is a good choice over here ?
Trying to avoid an extra object and its respective getters / setters ?
What ever you have right now is thread shared list. All threads operating on this object
(assuming only one instance of this object exists) share same list unless you synchronize.
I know you have your answer, but I did not understand the answer or the question, thus need to ask. So, you problem looks like this? You have a bunch of Callables that will perform some work on a SINGLE list, thus this list is shared among Threads? Then you need to make this List Thread Safe, and making a List of Objects Thread Safe is not that trivial (on your own), unless you use something already given by Java
I have a class Cache which picks up List<SomeObject> someObjectList from DB and stores it in static variable.
Now I have another thread A which uses this List as follows
class A extends Thread{
private List<SomeObject> somobjLst;
public A(){
somobjLst = Cache.getSomeObjectList();
}
void run(){
//somobjLst used in a loop here, no additong are done it , but its value is used
}
}
Now if at some point of time if some objects are added to Cache.someObjectList will it reflect in class A. I think it should as A only holds a refrence to it.
Will there will be any problem in A's code when content of Cache.someObjectList change?
EDIT:
As per suggestions :
if i make
void run (){
while(true){
synchronized(someObjList){
}
try{
Thread.sleep(INTERVAL);
}catch(Exception e){
}
}
}
will this solve problem?
Yes, the changes will be reflected in class A as well. Exactly as you say: A holds a reference to the exact same object as Cache.
Yes, it can lead to a problem if A doesn't expect it to change. It also can lead to a problem if the List implementation is not thread safe (most general-purpose implementations are not thread-safe!). Accessing a non-thread-safe data structure from two threads at the same time can lead to very nasty problems.
Sure, you are holding reference to collection in your thread. If collection is changed while you are iterating over it in thread ConcurrentModificationException will be thrown.
To avoid it you have to use some kind of synchronization mechanism. For example synchronize the iteration over collection and its modification done in other thread using synchronize(collection).
This is a kind of "pessimistic" locking.
Other possibility is to use collections from java.util.concurrent package.