separating threads but still keeping a common variable in java - java

My project group is creating a traffic simulation and we are not sure how to split threads properly. We have the update method below that has 1 variable delta. Now we want to split both for loops (updating vehicles in the first and the second updates all intersections etc). How does one split these into 2 threads yet still being able to give them the same value for delta? Is this even possible? We can only get it to work putting the entire method into 1 thread, but then we can not split them.
EDIT: the delta is a constantly changing variable (time passed) this is the reason it's hard to get both to use the same delta.
public void update(double delta){
for (int i = 0; i < this.vehicles.size(); i++) {
this.vehicles.get(i).update(delta);
}
for (int i = 0; i < this.updateables.size(); i++) {
this.updateables.get(i).update(delta);
}
this.simulationTime += delta;
}

If this.vehicles is a List, or something along those lines, create a parallel stream.
this.vehicles.stream().parallel().forEach(v->v.update(delta));
Then they should be run in parallel.
An alternative way, if you want more control over the process, use an executor service.
ExecutorService service = Executors.newFixedThreadPool(4);
Then submit each task.
List<Future<?>> futures = this.vehicles.map(
v->service.submit(
()->v.update(delta)
)
).collect(Collectors.toList());
Then to make sure all of the tasks complete.
futures.forEach(future->{
try{
future.get();
}catch(Exception e){
//two types of exceptions they both should be handled appropriately.
}
});

If I understand you right, delta may vary.
You can create two seperate Threads, for example here the one for the vehicles:
public class VehiclesUpdater extends Thread {
double delta;
List<Vehicle> vehicles;
public VehiclesUpdater(double delta, List<Vehicle> vehicles) {
this.delta = delta;
this.vehicles = vehicles;
}
#Override
public void run() {
for(int i=0;i<vehicles.size();i++) {
vehicles.get(i).update(delta);
}
}
}
Then, instead of calling the loop, just do as follows:
public void update(double delta) {
Thread t = new VehiclesUpdater(delta, vehicles);
t.start();
//the same here for the Updateables
}
EDIT:
Because you are concerning time issues, you may try an Observer/Observable-approach.
Let your Vehicle-class and your Updateable-class extend the Observer class: Observer
In the class which computes the delta-value(s), implement the Observable interface. If it changes, call the setChanged() method and after that the notifyObservers() method and give delta or an Double-Wrapper as param to it:
Double wrapper = new Double(delta);
setChanged();
notifyObservers(wrapper);
In your vehicle-class, you have to override the update-method of Observer:
//
#Override
public void update(Observable o, Object arg) {
this.updateDelta((Double)arg);
}
I just called your original update-method updateDelta for clarification - it should be possible to use method-overloading here as long as your update-method will use another param (double) and has the same method-head with public void update(...).

Related

How to use multithreads in java so that they take turns in a game

Trying to use n number of threads, where there are two different types of thread that needs to be being swapped between. So goes t1, x1, t2, x2, t3, x3.... where x and t are thread classes. I've been trying to use wait and notify but cant seem to get this to work. Or synchronisation.
All threads all need to access and modify the same list-array in their respective "turns" which i thought could be its own synchronised class, yet maybe an atomic variable would work also?
Any help is very appreciated.
"""
public String startGame(int threadNumbers, List<String> result, String fileLoc) throws IOException {
Players[] playerThreads = new Players[threadNumbers];
Card[] cardThreads = new Card[threadNumbers];
cardDeck cardD = new cardDeck(fileLoc);
for (int i = 0; i < (threadNumbers); i++) {
System.out.println(i);
playerThreads[i] = new Players(i+1, cardD);
if (i>0) {
playerThreads[i-1].next = cardThreads[i-0];
}
if (i==threadNumbers-1) {
playerThreads[i].next = cardThreads[0];
}
cardThreads[i] = new Card(i+1);
if (i>0) {
cardThreads[i-1].next = playerThreads[i-0];
}
if (i==threadNumbers-1) {
cardThreads[i].next = playerThreads[0];
}
new Thread(playerThreads[i]).start();
new Thread(cardThreads[i]).start();
Thread.yield();
Thread.yield();
}
synchronized (playerThreads[0]) {
playerThreads[0].notify();
"""
This is not working, but what needs to happen is they take a card from the deck in a looping way then start the game after they have a hand. The card threads also are just hands but are different as they dont "play" but just work.
Since this seems to be all in one (JVM) process, there's no need for multiple threading here: Just use a queue to track whose turn it is and who's turn it is next. After a player's turn, add them back to the end of the queue.
And actually, now that I think about it there's no reason this same solution couldn't work with multiple processes or over sockets.
Just use a queue
-- Edit --
So what you need is a class with a blocking method. For example
public class Player implements Runnable {
private Move nextMove;
public Move synchronized getMove() {
if (!nextMove) {
this.wait([add timeout if appropriate]);
}
Move next = nextMove;
nextMove = null;
return next;
}
public void run() {
while (true) {
Thread.sleep([someRandomTime]);
synchronized(this) {
if (nextMove == null) {
nextMove = new Move();
this.notify();
}
}
}
}
}
So still using your queue, you go through each Player and call getMove(), which will block until the player posts a move.
BTW, this kind of blocking is similar to how InputStream.read(buffer) works in sockets. The thread calling read waits until the other side of the stream sends some content.
-- Edit 2 --
And just as a reminder: Don't use synchronized, wait, notify or notifyAll on a Thread object.

Iterate through threads run via ThreadPoolTaskExecutor

I have a ThreadPoolTaskExecutor and when I create a Process which implements Runnable I run it via: executor.execute(process).
Now, before calling execute I want to check one field from Process object and compare it with ALL other currently running processes, executed by my ThreadPoolTaskExecutor. How I can do that, not generating a concurrent problem?
Code:
public class MyApp {
ThreadPoolTaskExecutor executor;
//...
public void runProcesses {
Process firstone = new Process(1);
Process nextOne = new Process(1);
// iterate through all processes started via executor and currently running,
// verify if there is any process.getX() == 1, if not run it
executor.execute(firstone );
//wait till firstone will end becouse have the same value of X
executor.execute(nextOne); // this cant be perform until the first one will end
}
}
public class Process {
private int x;
//...
public Process (int x){
this.x = x;
}
public int getX(){
return this.x;
}
}
I was thinking about createing simple Set of process started and add new one to it. But I have problem how to determine is it still running and remove it from set when it is done. So now I'm thinking about iterating through running threads, but completly dunno how.
I think that your initial idea is pretty good and can be made to work with not too much code.
It will require some tinkering in order to decouple "is a Runnable for this value already running" from "execute this Runnable", but here's a rough illustration that doesn't take care about that:
Implement equals() and hashCode() in Process, so that instances can safely be used in unordered sets and maps.
Create a ConcurrentMap<Process, Boolean>
You won't be using Collections.newSetFromMap(new ConcurrentHashMap<Process, Boolean>) because you'd want to use the map's putIfAbsent() method.
Try to add in it using putIfAbsent() each Process that you will be submitting and bail if the returned value is not null.
A non-null return value means that there's already an equivalent Process in the map (and therefore being processed).
The trivial and not very clean solution will be to inject a reference to the map in each Process instance and have putIfAbsent(this, true) as the first thing you do in your run() method.
Remove from it each Process that has finished processing.
The trivial and not very clean solution will be inject a reference to the map in each Process instance and have remove(this) as the last thing you do in your run() method.
Other solutions can have Process implement Callable and return its unique value as a result, so that it can be removed from the map, or use CompletableFuture and its thenAccept() callback.
Here's a sample that illustrates the trivial and not very clean solution described above (code too long to paste directly here).
Though #Dimitar provided very good solution for solving this problem I want to make an addition with another approach.
Having your requirements, it seems like you need to keep all submitted Processes, slicing them by x into separate queues and executing processes in queues one by one.
API of ThreadPoolExecutor empowers to enhance behaviour of Executor and I came to the following implementation of ThreadPoolExecutor:
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>()) {
private final ConcurrentMap<Integer, Queue<Runnable>> processes = new ConcurrentHashMap<>();
#Override
public void execute(Runnable command) {
if (command instanceof Process) {
int id = ((Process) command).getX();
Queue<Runnable> t = new ArrayDeque<>();
Queue<Runnable> queue = this.processes.putIfAbsent(id, t);
if (queue == null) {
queue = t;
}
synchronized (queue) {
queue.add(command);
if (!processes.containsKey(id)) {
processes.put(id, queue);
}
if (queue.size() == 1) {
super.execute(queue.peek()); // removal of current process would be done in #afterExecute
}
}
} else {
super.execute(command);
}
}
#Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (r instanceof Process) {
int id = ((Process) r).getX();
Queue<Runnable> queue = this.processes.get(id);
synchronized (queue) {
queue.poll(); // remove completed prev process
Runnable nextProcess = queue.peek(); // retrieve next process
if (nextProcess != null) {
super.execute(nextProcess);
} else {
this.processes.remove(id);
}
}
}
}
}

Exact same code (with multithreading) doesn't work on 2 different computers

I'm working at the moment on a simple Chess A.I. (calculate possible future turns, rate them, chosse the best one, + some tricks so you don't have to calculate every single turn). The code is written in Java and I'm using Netbeans. To make the calculations faster, I use multithreading. The code works roughly like this:
Main function makes first some calculations and then starts 8 threads.
the threads execute the main-calculations
when they finish, they set a boolean value in a boolean array (finished[]) true. This array is in the "main Class" (if you call it like this), where also the main function is.
during all this time the main function is waiting and checking constantly if every value of the finished[] - array is true. If that is the case, it continues it's work.
Now I have a strange problem. The code works perfectly on my PC, but when I run the EXACT same code on my laptop, the main function won't continue its work, after all values of the finished[]-array are true. I already made some changes in the code, so I can try it with different numbers of threads, but the result is always the same.
I have totally no idea what's going on here and would really appreciate it, if someone of you had any answers and/or suggestions!
If you need any more Information just ask, I'll try my best. :)
(Sorry for possible grammar mistakes, english isn't my native language, but I'm trying my best. ;))
So I was asked to show some Code I used in the program:
(Perhaps first a warning, yes I am still a big Noob in Java and this is my first time I work with threads so don't be shocked if you see terrible mistakes I possibly made. xD)
The main Class looks something like this:
public class Chess_ai_20 {
static boolean finished[] = new boolean[8];
Distributor[] Distributors = new Distributor[8];
...
public static void main(String[] args) {
boolean testing=false;
...
//some calculations and other stuff
...
Distributors[0] = new Distributor(...., "0"); //the String "0" will be the thread name.
Distributors[1] = new ...
...
Distributors[7] = new Distributor(...., "7");
for (int i = 0; i < 8; i++) {
Distributoren[i].start();
}
testing=false;
while(testing==false){
if(finished[0]==true && finished[1]==true && ... && finished[7]==true){
testing=true; //That's the point where I get stuck I suppose
}
}
System.out.println("I made it!");
}
public static void setFinished(int i) {
finished[i] = true;
System.out.println("finished [" + i + "] = " + finished[i]);
System.out.println(Arrays.toString(finished)); //To check how many values already are true
}
}
Then we got of course the class "Distributor"
public class Distributor extends Thread {
Thread t;
String threadname;
boolean running=false;
...
Distributor(......, String s) {
threadname=s;
...
...
}
#Override
public void start() {
running=true;
if (t == null) {
t = new Thread(this,threadname);
t.start();
}
}
#Override
public void run() {
if(running){
...
//Do the main calculations etc.
...
//All the Calculations habe been done at this point
Chess_ai_20.setFinished(Character.getNumericValue(threadname.charAt(0))); //Set the value of finished[] true in the main class
running=false;
}
}
}
As others have mentioned, using a Future would be much simpler and easy to understand. Below is a snippet demonstrating how you could rewrite your code. Check out the code in action.
First, you write a Callable to define the task that you want to do.
public class MyCallable implements Callable<Boolean> {
#Override
public Boolean call() {
// Do some job and return the result.
return Boolean.TRUE;
}
}
And then, you submit this task to an Executor. There are a lot of Executors in JDK. You want to go through the Concurrency Tutorial first.
ExecutorService executor = Executors.newFixedThreadPool(Runtime
.getRuntime().availableProcessors());
List<Callable<Boolean>> callables = new ArrayList<>();
for (int counter = 0; counter < 8; counter++) {
callables.add(new MyCallable());
}
List<Future<Boolean>> futures = executor.invokeAll(callables);
for (Future<Boolean> future : futures) {
System.out.println(future.get()); // You'd want to store this into an array or wherever you see fit.
}
executor.shutdown();
Remember that the futures returned by the executor are in the same order as the Callables you submitted (or added) to the Collection (in this case, an ArrayList). So you don't need to worry about returning the index, an ID or even the name of the Thread (if you assigned one) to map the corresponding result.

Java: Getting ExecutorService to produce repeatable behavior?

I have been trying to parallelize a portion of a method within my code (as shown in the Example class's function_to_parallelize(...) method). I have examined the executor framework and found that Futures & Callables can be used to create several worker threads that will ultimately return values. However, the online examples often shown with the executor framework are very simple and none of them appear to suffer my particular case of requiring methods in the class that contains that bit of code I'm trying to parallelize. As per one Stackoverflow thread, I've managed to write an external class that implements Callable called Solver that implements that method call() and set up the executor framework as shown in the method function_to_parallelize(...). Some of the computation that would occur in each worker thread requires methods *subroutine_A(...)* that operate on the data members of the Example class (and further, some of these subroutines make use of random numbers for various sampling functions).
My issue is while my program executes and produces results (sometimes accurate, sometimes not), every time I run it the results of the combined computation of the various worker threads is different. I figured it must be a shared memory problem, so I input into the Solver constructor copies of every data member of the Example class, including the utility that contained the Random rng. Further, I copied the subroutines that I require even directly into the Solver class (even though it's able to call those methods from Example without this). Why would I be getting different values each time? Is there something I need to implement, such as locking mechanisms or synchronization?
Alternatively, is there a simpler way to inject some parallelization into that method? Rewriting the "Example" class or drastically changing my class structuring is not an option as I need it in its current form for a variety of other aspects of my software/system.
Below is my code vignette (well, it's an incredibly abstracted/reduced form so as to show you basic structure and the target area, even if it's a bit longer than usual vignettes):
public class Tools{
Random rng;
public Tools(Random rng){
this.rng = rng;
}...
}
public class Solver implements Callable<Tuple>{
public Tools toolkit;
public Item W;
public Item v;
Item input;
double param;
public Solver(Item input, double param, Item W, Item v, Tools toolkit){
this.input = input;
this.param = param;
//...so on & so forth for rest of arguments
}
public Item call() throws Exception {
//does computation that utilizes the data members W, v
//and calls some methods housed in the "toolkit" object
}
public Item subroutine_A(Item in){....}
public Item subroutine_B(Item in){....}
}
public class Example{
private static final int NTHREDS = 4;
public Tools toolkit;
public Item W;
public Item v;
public Example(...,Tools toolkit...){
this.toolkit = toolkit; ...
}
public Item subroutine_A(Item in){
// some of its internal computation involves sampling & random # generation using
// a call to toolkit, which houses functions that use the initialize Random rng
...
}
public Item subroutine_B(Item in){....}
public void function_to_parallelize(Item input, double param,...){
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<Tuple>> list = new ArrayList<Future<Tuple>>();
while(some_stopping_condition){
// extract subset of input and feed into Solver constructor below
Callable<Tuple> worker = new Solver(input, param, W, v, toolkit);
Future<Tuple> submit = executor.submit(worker);
list.add(submit);
}
for(Future<Tuple> future : list){
try {
Item out = future.get();
// update W via some operation using "out" (like multiplying matrices for example)
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown(); // properly terminate the threadpool
}
}
ADDENDUM: While flob's answer below did address a problem with my vignette/code (you should make sure that you are setting your code up to wait for all threads to catch up with .await()), the issue did not go away after I made this correction. It turns out that the problem lies in how Random works with threads. In essence, the threads are scheduled in various orders (via the OS/scheduler) and hence will not repeat the order in which they are executed every run of the program to ensure that a purely deterministic result is obtained. I examined the thread-safe version of Random (and used it to gain a bit more efficiency) but alas it does not allow you to set the seed. However, I highly recommend those who are looking to incorporate random computations within their thread workers to use this as the RNG for multi-threaded work.
The problem I see is you don't wait for all the tasks to finish before updating W and because of that some of the Callable instances will get the updated W instead of the one you were expecting
At this point W is updated even if not all tasks have finished
Blockquote
// update W via some operation using "out" (like multiplying matrices for example)
The tasks that are not finished will take the W updated above instead the one you expect
A quick solution (if you know how many Solver tasks you'll have) would be to use a CountDownLatch in order to see when all the tasks have finished:
public void function_to_parallelize(Item input, double param,...){
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<Tuple>> list = new ArrayList<Future<Tuple>>();
CountDownLatch latch = new CountDownLatch(<number_of_tasks_created_in_next_loop>);
while(some_stopping_condition){
// extract subset of input and feed into Solver constructor below
Callable<Tuple> worker = new Solver(input, param, W, v, toolkit,latch);
Future<Tuple> submit = executor.submit(worker);
list.add(submit);
}
latch.await();
for(Future<Tuple> future : list){
try {
Item out = future.get();
// update W via some operation using "out" (like multiplying matrices for example)
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown(); // properly terminate the threadpool
}
then in the Solver class you have to decrement the latch when call method ends:
public Item call() throws Exception {
//does computation that utilizes the data members W, v
//and calls some methods housed in the "toolkit" object
latch.countDown();
}

How to execute multiple instances of a method with different inputs in parallel in java?

I have a method which takes a list and do some processing on it and it updates another global list. I need to run multiple instances of this method with different lists input in parallel.
Does multi-threading support this? If yes, how can i use it i.e.: what shall i put in the thread? Examples are highly appreciated.
I am thinking of having a static list in the thread class which gets updated by the different instances of the thread while running (the list contains strings and counters, so the update is adding new strings or increasing the counters of existing ones).. i need to read whatever gets added to this global list every 10 seconds and print it.. is using static list suitable for this and how can i make it thread safe?
Yes, that's a very common usage of multithreaded programming.
class ListProcessor implements Runnable {
/* field/s representing param/s */
public ListProcessor(/* param/s */) {
/* ... */
}
#Override
public void run() {
/* process list */
}
}
Then, when you want to actually process some lists.
class SomeClass {
ExecutorService listProcessor;
public SomeClass(/* ... */) {
listProcessor = ExecutorService.newFixedThreadPool(numThreads);
/* for each thread, however you want to do it */
listProcessor.execute(new ListProcessor(/* param/s */));
/* when finished adding threads */
listProcessor.shutdown();
/* note that the above two lines of code (execute/shutdown) can be
* placed anywhere in the code. I just put them in the constructor to
* facilitate this example.
*/
}
}
#purtip31 has a start for the parallel processing stuff.
I'm concerned about the results - you mention that you update a "global list". If multiple threads at a time are trying to update that list at the same time there could be problems. A couple of options:
Make sure that list is properly thread safe. This may or may not be easy - depends on exactly what is getting changed.
Use ExecutorService, but with the invokeAll() method, which runs a bunch of Callables in parallel and waits till they are all done. Then you can go through all of the results and update them one at a time. No threading issues with the results. This means that your code will have to implement Callable instead of Runnable (not a big deal). I have a blog with an example here
Well Sam...i m not much cleared with your question.....
try this out....
Following is a code which would help u to run mulitple instances.......
Main thread
public class mainprocess
{
public static LinkedList globallist;
public static String str;
public int num;
public static void main(String Data[])
{
globallist = new LinkedList();
// LinkedList will be passed as pass by reference.....
// globalist is made static and assigned likewise for global use..
childprocess.assignlist(globallist);
childprocess p1 = new childprocess("string input"); // a string input...
childprocess p2 = new childprocess(number input); // a number input...
p1.t.join();
p2.t.join();
}
}
The Child Thread.....
public class childprocess implements Runnable
{
public Thread t1,t2;
public boolean inttype,stringtype;
String string;
int num;
public static LinkedList temp = new Linkedlist();
public static assignlist(LinkedList ll)
{
temp = ll;
}
public childprocess(String str)
{
string = str;
t1 = new Thread(this,"stringThread");
t1.start();
}
#override
public childprocess(int n)
{
num = n;
t2 = new Thread(this,"numberThread");
t2.start();
}
#override
public void run()
{
// Both will be executed in a threader manner based on the condition...
if(Thread.currentThread().getName().equals("stringThread")
{
// your process using string......
childprocess.temp.add(str);
}
else if(Thread.currentThread().getName().equals("numberThread")
{
// your process using number.....
chilprocess.temp.add(num);
}
}
}
If you are using functions that should be restricted to only one thread at a time...
include the syntax....
public synchronized func_type func_name()
{
}

Categories

Resources