Am I correctly implementing these Java threads? The goal is to have ten concurrent threads who compute a sum from 1 to (upper bound 22 + i). I'm trying to identify the name and print it when running the thread, then print the result when the thread exits. Currently, I have all of the results printing at the same time in a random order and I am not sure if I am correctly getting the information when the thread begins and ends.
public class threads {
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
final int iCopy = i;
new Thread("" + i) {
public void run() {
int sum = 0;
int upperBound = 22;
int lowerBound = 1;
long threadID = Thread.currentThread().getId();
for (int number = lowerBound; number <= upperBound; number++){
sum = sum + number + iCopy;
}
System.out.println(threadID + " thread is running now, I and will compute the sum from 1 to " + (upperBound + iCopy) + ". The i is : " + iCopy);
System.out.println("Thread id #" + threadID + ", the "+ sum + " is done by the thread.");
}
}.start();
}
}
}
I have executed your code and observed that all threads are running properly 10 in this case. Since threads are invoked in random order that is why this behavior might be seen but I an sure that all threads for running fine and executing the functionality you require.
Any how in output i saw that in for loop the value should start from 0 to 9 but here even this is random, may be because some threads are sleeping while executing and giving way to other threads.
Hope this helps
Thanks.
The order the threads run in will depend entirely on the JVM being used and underlying resources.
If you have several cores (cpus) available, your code may run completely differently to a single core.
Essentially, your main loop runs to the end in a single thread, firing 10 new threads, and puts the start method in a process queue. Other processors may start running those threads. Each extra thread causes different total load, so they run slightly differently (performance wise) on each processor, meaning they run faster/slower, and end in different times.
Your code demonstrates this very well.
Related
So below is my code where Buyers and Sellers interact with Cars and a Car Showroom. It runs as it should, as far as I know. However, Threads only run after day 20+ in the While Loop in Main. Could anyone help point out why this is?
public static void main(String[] args) {
CarShowroom carShowroom = new CarShowroom();
Random rand = new Random();
int day = 1;
while (day <= 30){
System.out.println("Day " + day + " beginning. There are " + carShowroom.getCars().size() + " cars in the showroom today.");
int randomSeller = rand.nextInt(3);
int randomBuyer = rand.nextInt(3);
for (int j = 0; j <= randomSeller; j++){
Seller seller = new Seller(carShowroom);
Thread mySellerThread = new Thread(seller);
mySellerThread.start();
}
for (int i = 0; i <= randomBuyer; i++){
Buyer buyer = new Buyer(carShowroom);
Thread myBuyerThread = new Thread(buyer);
myBuyerThread.start();
}
day++;
}
}
}
I think perhaps your loop is executing quicker than Thread.start() will start.
It is either caused by the fact that spawned threads are not immediately ready to execute code or simply you might have single core machine and main thread occupies cpu then the other threads have to wait until cpu time slice assigned to the main thread ends. In order to achieve tiny bit of determinism within yours program execution, you could put Thread.sleep(100) in the main loop to create an opportunity for the other threads to run. That should alter the order of execution.
If I understand task correctly, then buyers and sellers should make some deals before the day ends and then new day should start (not earlier).
If so then using Thread.sleep is bad solution here for two reasons
If you set short delay then new day may start when deals are not done yet
If you set long delay (and in real prod environment it is quite a task to determine what is long enough to cover all possible future scenarios) then in most cases you will waste thread (*) + your code could be visible slow
Proper solution will be not guessing if deals are done or not but waiting for the event "all deals are done".
It could be achieved in a multiple ways (CountDownLatch, atomic counter etc) but easiest is to wait when all threads started for a day are stopped
while (day <= 30){
System.out.println("Day " + day + " beginning. There are " + carShowroom.getCars().size() + " cars in the showroom today.");
int randomSeller = rand.nextInt(3);
int randomBuyer = rand.nextInt(3);
List<Thread> allThreads = new List<>(randomSeller+randomBuyer+2);
for (int j = 0; j <= randomSeller; j++){
Seller seller = new Seller(carShowroom);
Thread mySellerThread = new Thread(seller);
mySellerThread.start();
allThreads.add(mySellerThread);
}
for (int i = 0; i <= randomBuyer; i++){
Buyer buyer = new Buyer(carShowroom);
Thread myBuyerThread = new Thread(buyer);
myBuyerThread.start();
allThreads.add(myBuyerThread);
}
for (Thread t : allThreads) {
t.join();
}
// "all deals are done"
day++;
}
t.join causes main thread (which loops the days) to wait until thread is done (== seller.run() or buyer.run() methods are completed). If thread is already finished then t.join is also safe, it will just exit.
Once you verified all sellers and buyers threads are done, you know "all deals are done"
(*) For example, if your days loop is executed in the thread taken from the pool then while you are doing sleep thread does not do any job and cannot be used for any other task as well.
I tried to compile the example from Thinking in Java by Bruce Eckel:
import java.util.concurrent.*;
public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d; // No optimization
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
public void run() {
Thread.currentThread().setPriority(priority);
while(true) {
// An expensive, interruptable operation:
for(int i = 1; i < 100000; i++) {
d += (Math.PI + Math.E) / (double)i;
if(i % 1000 == 0)
Thread.yield();
}
System.out.println(this);
if(--countDown == 0) return;
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(
new SimplePriorities(Thread.MIN_PRIORITY));
exec.execute(
new SimplePriorities(Thread.MAX_PRIORITY));
exec.shutdown();
}
}
According to the book, the output has to look like:
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-6,10,main]: 4
Thread[pool-1-thread-6,10,main]: 3
Thread[pool-1-thread-6,10,main]: 2
Thread[pool-1-thread-6,10,main]: 1
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-1,1,main]: 5
...
But in my case 6th thread doesn't execute its task at first and threads are disordered. Could you please explain me what's wrong? I just copied the source and didn't add any strings of code.
The code is working fine and with the output from the book.
Your IDE probably has console window with the scroll bar - just scroll it up and see the 6th thread first doing its job.
However, the results may differ depending on OS / JVM version. This code runs as expected for me on Windows 10 / JVM 8
There are two issues here:
If two threads with the same priority want to write output, which one goes first?
The order of threads (with the same priority) is undefined, therefore the order of output is undefined. It is likely that a single thread is allowed to write several outputs in a row (because that's how most thread schedulers work), but it could also be completely random, or anything in between.
How many threads will a cached thread pool create?
That depends on your system. If you run on a dual-core system, creating more than 4 threads is pointless, because there hardly won't be any CPU available to execute those threads. In this scenario further tasks will be queued and executed only after earlier tasks are completed.
Hint: there is also a fixed-size thread pool, experimenting with that should change the output.
In summary there is nothing wrong with your code, it is just wrong to assume that threads are executed in any order. It is even technically possible (although very unlikely), that the first task is already completed before the last task is even started. If your book says that the above order is "correct" then the book is simply wrong. On an average system that might be the most likely output, but - as above - with threads there is never any order, unless you enforce it.
One way to enforce it are thread priorities - higher priorities will get their work done first - you can find other concepts in the concurrent package.
I need to write two programs. 1 sequential (Done) and 1 parallel and I've done something but i don't know if I've made it parallel or not and i also need to know:
If (Thread.State state = Thread.currentThread().getState();) is the code to display the status of a thread
how to assign different threads to different processors (4 cores)
How to display the status of the processor
calculation for each processor
how to generate error messeges(Memory Consistency Errors, etc.)
Following is my code:
class Threads implements Runnable {
#Override
public void run() {
Thread t = Thread.currentThread();
Thread.State state = Thread.currentThread().getState();
String Assignment = "calculations in array";
String name = "os.name";
String version = "os.version";
String architecture = "os.arch";
String[] array = new String[1312500];
int size = array.length;
Random r = new Random();
int[] values = new int[1312500];
int sumarray = 0;
int CountD = 0;
for (int i = 0; i < values.length; i++) {
int randomint = r.nextInt(100);
values[i] = randomint;
if ((values[i] % 2 != 0) && (values[i] >= 25 && values[i] <= 75)) {
sumarray += values[i];
CountD++;
}
}
System.out.println(t.getName());
System.out.println("Thread Id " + t.getId());
System.out.println("Thread Priority " + t.getPriority());
System.out.println("status " + state);
System.out.println("OS Name: " + System.getProperty(name));
System.out.println("OS Version: " + System.getProperty(version));
System.out.println("OS Architechture: " + System.getProperty(architecture));
System.out.println(Assignment);
System.out.println("Size of the Array is: " + array.length);
System.out.println("Total number of system cores(processors): " + Runtime.getRuntime().availableProcessors());
System.out.println("Difference of Array and Processors 1312500/4 = "
+ array.length / Runtime.getRuntime().availableProcessors());
System.out.println("The size of array is divisible by the number of processors");
System.out.println("Summary is: " + sumarray);
System.out.println("The Average is: " + (sumarray / CountD));
}
}
Main class:
class Concurrent {
public static void main(String[] args) {
Thread t1 = new Thread(new Threads());
t1.start();
Thread t2 = new Thread(new Threads());
t2.start();
Thread t3 = new Thread(new Threads());
t3.start();
Thread t4 = new Thread(new Threads());
t4.start();
}
}
[I need to know] If Thread.State state = Thread.currentThread().getState(); is the code to display the status of a thread.
That declares a variable named state and initializes it with the state of the thread in which it is executed. (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html
That code snippet doesn't display anything, but the subsequent System.out.println("status " + state); will write a representation of the state out to the console.
I have no way of knowing know whether Thread.State corresponds to what you call "status", but calling Thread.currentThread().getState(); yields no information because the state of any thread will always be RUNNABLE while it is calling getState().
[I need to know] how to assign different threads to different processors
I bet you don't.
What you are asking about is called "processor affinity." Most programs rely on the operating system to automatically schedule runnable threads on available CPUs. It's only very sophisticated programs (and note, "sophisticated" does not always equal "good") that need to tinker with it.
There is no standard way to set the CPU affinity of Java threads, but there might be some means that you can use on your particular operating system. You can google "Java processor affinity" for more info.
[I need to know] How to display the status of the processor
You're going to have to explain what "status" means and also, which processor, and when?
Depending on what "status" means, If you write code to ask for the "status" of the same processor that the code is running on, then the answer probably will never change. Just like how the result of Thread.currentThread().getState() never changes.
Processor "status" is the sort of thing that sysadmins of big data centers like to see plotted on charts, but they seldom are useful within a program unless, once again, you are doing something very sophisticated.
[I need to know] how to generate error messeges.
The simplest way to do that is to use System.out.println(...) or System.err.println(...)
Maybe you really meant to ask something else, like how to know when to report an error, or how to handle exceptions.
Most Java library routines throw an exception when something goes wrong. All you have to do in that case is completely ignore it. If you don't write any code to handle the exception, then your program will automatically print an error message and stop when the exception is thrown.
how to assign different threads to different processors (4 cores)
Let's leave this decision to java runtime. From programmer perspective, try to use the features available to you.
For effective utilizaiton of CPU cores, have a look at this question:
Java: How to scale threads according to cpu cores?
Regarding processor affinity, you can check posts:
Java thread affinity
http://tools.assembla.com/Behemoth/browser/Tests/JAVA/test/src/main/java/test/threads/ThreadAffinity.java ( written by BegemoT)
But you should avoid these type of things and focus on business logic.
how to generate error messeges(Memory Consistency Errors, etc.)
You can easily generate memory consistency errors.
Do not protect your code with thread safe constructs like synchronized or Lock and allow multiple threads to update data from your class.
Have a look at this documentation page
Refer to documentation links for better understanding of multi-threading concepts.
I have a program that applies a median filter to an array of over 2 million values.
I'm trying to compare run times for sequential vs parallel on the same dataset. So when I execute the program, it does 20 runs, every run is timed, and an average of the 20 times is outputted to the console.
ArrayList<Double> times = new ArrayList<>(20);//to calculate average run time
for (int run = 1; run < 21; run++) //algorithm will run 20 times
{
long startTime = System.nanoTime();
switch (method)
{
case 1: //Sequential
filt.seqFilter();
break;
case 2: //ForkJoin Framework
pool.invoke(filt); //pool is ForkJoin
break;
}
Double timeElapsed = (System.nanoTime() - startTime) / 1000000.0;
times.add(run - 1, timeElapsed);
System.out.println("Run " + run + ": " + timeElapsed + " milliseconds.");
}
times.remove(Collections.max(times)); //there's always a slow outlier
double timesSum = 0;
for (Double e : times)
{
timesSum += e;
}
double average = timesSum / 19;
System.out.println("Runtime: " + average);
filt is of type FilterObject which extends RecursiveAction. My overridden compute() method in FilterObject looks like this:
public void compute()
{
if (hi - lo <= SEQUENTIAL_THRESHOLD)
{
seqFilter();
}
else
{
FilterObject left = new FilterObject(lo, (hi + lo) / 2);
FilterObject right = new FilterObject((hi + lo) / 2, hi);
left.fork();
right.compute();
left.join();
}
}
seqFilter() processes the values between the lo and hi indices in the starting array and adds the processed values to a final array in the same positions. That's why there is no merging of arrays after left.join().
My run times for this are insanely fast for parallel - so fast that I think there must be something wrong with my timer OR with my left.join() statement. I'm getting average times of around 170 milliseconds for sequential with a filtering window of size 3 and 0.004 milliseconds for parallel. Why am I getting these values? I'm especially concerned that my join() is in the wrong place.
If you'd like to see my entire code, with all the classes and some input files, follow this link.
After some testing of your code I found the reason. It turned out that the ForkJoinPool runs one task instance only once. Subsequent invoke() calls with the same task instance will return immediately. So you have to reinstantiate the task for every run.
Another problem is with the parallel (standard threads) run. You are starting the threads but never waiting for them to finish before measuring the time. I think You could use the CyclicBarrier here.
With the mentioned fixes I get roughly the same time for ForkJoin and standard threads. And it's three times faster than sequential. Seems reasonable.
P.S. You are doing a micro-benchmark. It may be useful to read answers to that question to improve your benchmark accuracy: How do I write a correct micro-benchmark in Java?
I'm working on an 8-core machine and am performing a computationally heavy task. However, each execution of the task (i.e., iteration of for loop) is rather independent of the previous one. There are only some variables that are 'summed up' from one execution to the next. I'm guessing this is a good example for parallelizing/threading but I'm not sure how to go about it.
Here's how the code looks. As of now, it's just part of the main method in my main executor class:
double testerPayoffSum = 0.0, developerPayoffSum = 0.0;
Random seed = new Random();
try {
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
testerPayoffSum += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
System.out.print("Output: ERASER Games played; Number of developers caught");
System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
} catch(Exception e){sendEmailAlert("Execution Failed with Exception");}
I'd like to parallelize the for-loop computation if possible and keep summing up the testerPayoffSum and developerPayofffSum variables. How might I achieve this?
Note: Each execution of the for loop takes about 20-30 minutes depending on the input size (as set by the various GameConstants). Even for a small number of MAX_GAMES the above takes close to 2-3 hours.
Create a thread object implementing Callable which returns a Future object containing your testerPayoffSum and developerPayoffSum, start the calculation and sum the results obtained from the Futures (See also https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6).
are you absolutely sure you have no dependency ?
1.used classes must not share any variables
if it does then you have to add locks
but it will affect performance
if some shared variables are used extensively
then the performance can drop significantly even bellow the non-parallel execution
2.used classes must not use any kind of machine learning.
there is no solution for this
because parallelization will corrupt your results
Now how to do it (I am not JAVA coder so I stick to C++ code).
//--- globals and headers -----------------------------------------------------
unsigned long __stdcall function(LPVOID p);
Random seed = new Random();
const int N=8; // threads count (<=CPU count)
int id[N]; // thread id
int max[N]; // number of games per thread
double testerPayoffSum[N]; // sum to separate variables to avoid locks need
double developerPayoffSum[N];
volatile int run=0,stop=0; // thread control variables run is number of running threads and stop force stop...
//--- main code ---------------------------------------------------------------
// init some variables ... may be the seed init will be better here too
int i;
for (i = 0; i < N; i++)
{
id[i]=i;
max[i]=GameConstants.MAX_GAMES / N;
testerPayoffSum[i]=0.0;
developerPayoffSum[i]=0.0;
}
max[0]=GameConstants.MAX_GAMES % N;
// create threads
for (i = 0; i < N; i++)
{
HANDLE hnd=CreateThread(0,0,function,&id[i],0,0);
if (hnd!=NULL) CloseHandle(hnd); // this line is important !!!
// because if you do not close Handle it will be allocated until the end of app
// handle leaks are nasty and cause weird OS behaviour
// I saw many times this bug in commercial drivers
// it is a nightmare for 24/7 software
}
// wait for them
while (run) Sleep(200);
// sum the results to [0]
for (i = 1; i < N; i++)
{
testerPayoffSum[0] +=testerPayoffSum[i];
developerPayoffSum[0]+=developerPayoffSum[i];
}
// here do what you need to do with the results
//--- thread function ---------------------------------------------------------
unsigned long __stdcall function(LPVOID p)
{
run++;
int ix=((int*)p)[0];
for (i = 0; i < max[ix]; i++)
{
if (stop) break;
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
testerPayoffSum[ix] += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum[ix] += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
// do not call any visual stuff from thread !!! sometimes it can cause a lot of problems ...
// instead cretae some global string variable and set it to what shoud be printed out
// and inside wait while loop in main code add if string != "" then System.out.print(string);
// but in that case you should add lock to it.
// System.out.print("Output: ERASER Games played; Number of developers caught");
// System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
//Sleep(100); // well placed sleep
}
run--;
}
[Notes]
from your code I am assuming that GameConstants is shared variable !!!
if it is only for read than it is OK
but if you do also write to it inside thread (I suspect that yes)
then you have a big problem because you need to add locks inside your game class then ...
if no machine learning is done then you could avoid this
by creating separate GameConstants variables for each thread like ... GameConstants[N]
but you need to rewrite the code so it access the GameConstants[ix] and not GameConstants
[lock]
have no clue how locks are implemented in JAVA
but you can also use your own something like this
class _lock
{
public:
volatile bool locked;
_lock() { locked=false; }
void lock() { while(locked) Sleep(1); locked=true; }
void unlock() { locked=false; }
};
// now for each shared variable (or group of variables) add one global _lock variable
_lock l1; int sv1; // shared variable 1 and her lock
// any write access and sometimes also read access needs lock
l1.lock();
sv1++;
l1.unlock();
beware that locks can sometimes cause App freeze especially while heavy duty use.
does not matter if it is own lock or OS lock
this occurs mainly while mixing visual stuff or some OS calls inside threads and not in main thread
in that case sometimes a well placed sleep helps but avoid OS calls inside threads if you can
because it cause very many other problems ...
also try to be locked as small time as possible because in case of conflict the conflicting threads are stopped !!!
therefore you cannot just add lock at the start of loop and unlock at the end
because the parallelism speedup will be lost then
Declare a queue to collect results and submit tasks to a thread pool:
final ArrayBloclingQueue<PlayerPayoffs> queue=new ArrayBloclingQueue<PlayerPayoffs>();
Executor exec=new Executors.newFixedThreadPool(N); // number of threads depends on hardware
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
exec.execute(new Runnable(){
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
queue.put(payoffs);
});
}
Then collect and sum results:
double testerPayoffSum = 0.0, developerPayoffSum = 0.0;
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
PlayerPayoffs payoffs=queue.take();
testerPayoffSum += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
System.out.print("Output: ERASER Games played; Number of developers caught");
System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
}