Divide Loop Execution According to Threads In Java - java

suppose i have a method run as following,
public void run()
{
for(i=loopstart;i<loopend;i++){
//some code here to execute. no dependency exists
}
loopstart & loopend variables have the min and max value of loop execution.
now what i have to do is to divide this loop execution in 2 to 5 threads in order to execute in parallel. to accomplish this, i have changed this method as
public void run()
{
for(i=thread_start; i<thread_end; i++)
//some code here to execute.
}
the variables thread_start and thread_end are the ranges each thread has to run. so how it would be best to divide loop execution. suppose i have the loop execution in the range
5-94
and i want to divide it to many ranges for execution depending on number of threads.
e.g.
threads ranges
2 5-44, 45-94
3 5-34, 35-65, 66-94
these are just examples (not exact). i want to divide its execution on the basis of threads available.
so for 2 threads,
thread_start=5 ,thread_end=44 1st thread
thread_start=45 ,thread_end=94 2nd thread.
how should (using java code) i divide loop execution in almost same length ranges?

public class Looper implements Runnable {
private int start;
private int end;
public Looper(int start, int end){
this.start = start;
this.end = end;
}
#Override
public void run() {
for(int i=start; i<end; i++){
System.out.println("thread id : " + Thread.currentThread().getId() + "; index : " + i) ;
}
}
}
public class Test {
public static void main(String[] args){
Thread looper1 = new Thread(new Looper(1,1000));
Thread looper2 = new Thread (new Looper(1001,2000));
looper1.start();
looper2.start();
}
}
this is what you need? If you need to get available Threads at runtime, you might consider using ThreadPool.

Related

How to fix async java code failing even with thread safety implementation?

I am working on a codebase that implements something similar to this. We are having issues with one of the threads failing to synchronize with other threads when the value of count is incremented, thus going into an infinite loop.
The problem seems to come from the non-atomic behaviour of the post-increment operator.
You can find the code Repl here NB: You may need to run the code at least 3 times to observe it.
I need support to implement increment of count by as many threads as possible in a thread safety way.
class Main {
static volatile Integer count = new Integer(0); //boxed integer is intentional to demonstrate mutable instance
static final void Log(Object o) {
System.out.println(o);
}
static synchronized void increaseCount(){
count++;
}
static synchronized Integer getCount(){
return count;
}
public static void main(String[] arg) throws InterruptedException {
new Thread(() -> {
while (getCount() != 60) {
increaseCount();
Log(count +" thread A");
}
}).start();
new Thread(() -> {
while (getCount() != 20) {
increaseCount();
Log(count +" thread B");
}
}).start();
new Thread(() -> {
while (getCount() != 50) {
increaseCount();
Log(count+" thread C");
}
}).start();
}
}
If many threads are incrementing a shared counter, there is no guarantee about which thread will see a particular value of the counter. To make sure a particular thread sees a particular value, that thread has to see every value of the counter. And then you might as well just have one thread, because they are all working in lockstep with each other.
If you want to do some work for every value of the counter, with special handling for particular values, and you want to parallelize that workload, every thread needs to be prepared to perform the special handling. Here's an example of how you could do that:
class Main {
private static class Worker implements Runnable {
private final AtomicInteger counter;
private final Set<Integer> triggers;
Worker(AtomicInteger counter, Set<Integer> triggers) {
this.counter = counter;
this.triggers = triggers;
}
public void run() {
String name = Thread.currentThread().getName();
while (!triggers.isEmpty()) {
int value = counter.getAndIncrement();
try { /* Simulate actually doing some work by sleeping a bit. */
long delay = (long) (-100 * Math.log(1 - ThreadLocalRandom.current().nextDouble()));
TimeUnit.MILLISECONDS.sleep(delay);
} catch (InterruptedException ex) {
break;
}
boolean triggered = triggers.remove(value);
if (triggered) {
System.out.println(name + " handled " + value);
} else {
System.out.println(name + " skipped " + value);
}
}
}
}
public static void main(String[] arg) throws InterruptedException {
AtomicInteger counter = new AtomicInteger();
Set<Integer> triggers = new ConcurrentSkipListSet<>();
triggers.add(60);
triggers.add(20);
triggers.add(50);
int concurrency = 4;
ExecutorService workers = Executors.newFixedThreadPool(concurrency);
for (int i = 0; i < concurrency; ++i) {
workers.execute(new Worker(counter, triggers));
}
workers.shutdown();
}
}
The number of worker threads can be adjusted so that it makes sense given the number of cores on your machine, and the real workload (how CPU or I/O intensive the tasks are).
In this approach, each value of the counter is processed by just one thread, and it doesn't matter which thread gets a "sentinel" value. But, when all the sentinel values have been processed, all the threads shut down. Threads coordinate with each other through the counter, and the set of "triggers", or sentinel values that they need to handle.

Java: Why is my synchronized output still so random

So I'm practicing with synchronization for the first time. I'm trying to implement a practice concept that was described in general on the Oracle Java Concurrency tutorial.
The idea is to have a special Counter object, with methods to increment, decrement, and show value. My goal was to get it run by two different threads to generate random conflicts, and to then solve those conflicts through synchronization. So far I feel like the second part is not working, and I can't figure out what I'm doing wrong.
The code I'm pasting below is simple. There are two threads, with two runnables. Each runnable:
1) contains a reference to the same, single Counter object
2) runs a loop five times
3) sleeps for 1 second each time the loop runs
4) prints the current value of the Counter.
The only difference between MyRunnable1 & MyRunnable2 is that the first one increments the counter, and the second one decrements the counter.
Obviously when I ran it without synchronized methods it produced random results. But even after I synchronized the methods, the results were still apparently random.
SAMPLE RESULTS 1:
1
0
1
0
1
0
-1
0
1
0
SAMPLE RESULTS 2:
-1
0
1
0
1
0
1
0
-1
0
WHAT I THINK IT SHOULD BE: It should consistently go 1 0 1 0 1 0 etc etc until all the loops are finished. If I'm wrong there, if it's the way I'm thinking about thread behavior, please point that out.
Below is my code. All thoughts/advice appreciated. This is my first attempt at using synchronization in any way, I want to get it down because it's such an important concept.
public class CounterSync {
public static void main(String[] args){
Counter c = new Counter();
Thread t1 = new Thread(new MyRunnable1(c));
Thread t2 = new Thread(new MyRunnable2(c));
t1.start();
t2.start();
System.out.println("Done");
}
public static class Counter{
private int c = 0;
public synchronized void increment(){
c++;
}
public synchronized void decrement(){
c--;
}
public synchronized int value(){
return c;
}
}
public static class MyRunnable1 implements Runnable{
private Counter c;
public MyRunnable1(Counter c){
this.c = c;
}
#Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.increment();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
public static class MyRunnable2 implements Runnable{
private Counter c;
public MyRunnable2(Counter c){
this.c = c;
}
#Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.decrement();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
Synchronization does not mean ordering. Perhaps the word 'synchronization' is misleading. In your case, when one has synchronized methods, it means that at a given instant maximum one thread can be running a synchronized method on the object in question.
You can read 'synchronized' as 'one at a time'.
Whenever you have more than one thread running, how much each thread will progress is decided by the system. Further, Thread.sleep is guaranteed to sleep at least for the given interval, but not exact. The two facts combined will give you the random ordering.

incrementing a static variable thru' 100 different threads without synchronisation, yet getting the final result as 100

I'm incrementing a static variable thru' 100 different threads without synchronisation, yet getting the final result as 100. I've run this code several times and have got same result. Does my code then not require synchronisation? I'm using BlueJ IDE to run the code
public class Main {
private final static int MAX_THREADS = 100;
public static void main(String[] args) {
Thread[] threads = new Thread[MAX_THREADS];
for(int i=0; i<MAX_THREADS; i++) {
threads[i] = new Thread(new Job(), "Thread-" + i);
threads[i].start();
try{
Thread.sleep((int)(Math.random() * 1000));
}catch(InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0; i<MAX_THREADS; i++) {
try {
threads[i].join();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("Final Value: %d\n", Job.getSuccessCount());
}
}
public class Job implements Runnable {
private static int successCount;
public static int getSuccessCount() {return successCount;}
#Override
public void run() {
System.out.printf("%s: Incrementing successCount %d\n", Thread.currentThread().getName(), successCount);
try{
Thread.sleep((int)(Math.random() * 10000));
}catch(InterruptedException e) {
e.printStackTrace();
}
successCount++;
System.out.printf("%s: Incrementing Complete %d\n", Thread.currentThread().getName(), successCount);
}
}
Basically in you code, due to the sleep statements (both in the Thread and by the launcher), you are effectively kicking off the threads allowing for plenty of non busy time to update. That is why it is working. If you code was really multi-threaded, the you would face synchronization issues.
Adding to Wombat's Answer. The final result will always be 100 because you do a Unary Operation after The Sleep in Job class. Basically the read-modify-write commands can run sequentially per Job if the Java Scheduler didn't change the status of the Thread while performing the following.
successCount++
But if you change the Job source code to read-sleep-modify-write then you will definitely see stale value as following.
public class Job implements Runnable {
private static int successCount;
public static int getSuccessCount() {return successCount;}
#Override
public void run() {
System.out.printf("%s: Incrementing successCount %d\n", Thread.currentThread().getName(), successCount);
int sc = successCount; // Read
try{
Thread.sleep((int)(Math.random() * 10000)); // Sleep
}catch(InterruptedException e) {
e.printStackTrace();
}
successCount = sc++; // Modify-Write
System.out.printf("%s: Incrementing Complete %d\n", Thread.currentThread().getName(), successCount);
}
}
With this 2 Threads can read and then sleep and then wake up and write the same value to successCount overwriting the original value.
Your code currently doesn't need synchronization, as no two treads access the same variable at the same time. In other words, only 1 thread in your application is incrementing the variable.
In this case, it is due to the fact that incrementing the variable takes less than Math.random() *1000. Why is it so? Let's observe the threads:
Main Thread:
Launches and starts a thread
Executes both Math.random() and Thread.sleep()
Loops again
While the main thread is doing step 2, the new thread is:
Incrementing variable
Going to sleep
In this case, once the new thread goes to sleep, it just is killed right after, therefore, for our purpose we can regard it as if the thread terminates right after step 1, as it stops affecting the variable (it has no influence on the variable after step 1).
In order for a synchronization problem to occur, two new threads need to access the variable at once. For this to happen, main thread must launch a new thread before the first new thread finishes incrementing. For that to happen, main thread must be faster in: executing Math.random(), Thread.sleep(), and creating a new thread, all before the other thread finishes incrementing. This is obviously not the case, and thus no 2 threads will increment at once, and no synchronization error will occur.
If you do the sums you'll see that you have an average of ten threads running at the same time, all sleeping for an average of five seconds and then doing an increment. So on average the increments won't be closer together than half a second, and the fact their starting is also spaced out by an average of half a second makes that a full second on average. There is essentially no concurrency here at all.

CyclicBarrier not working as expected

I am trying to simulate a triatlon competition using CyclicBarrier but it doesn't work as expected and I don't know why.
Each part of the competition has to wait till all the runners have completed the previous one, but it seems like it's waiting forever.
This is the piece of code for the phase one:
class Runner implements Runnable
{
private CyclicBarrier bar = null;
private static int runners;
private static double[] time;
private int number;
public static String name;
public Runner(int runners, String name)
{
time = new double[runners];
for (int i=0; i<runners; i++)
time[i] = 0;
this.name= name;
}
public Runner(CyclicBarrier bar, int number)
{
this.bar = bar;
this.number = number;
}
public void run()
{
try { int i = bar.await(); }
catch(InterruptedException e) {}
catch (BrokenBarrierException e) {}
double tIni = System.nanoTime();
try { Thread.sleep((int)(100*Math.random()); } catch(InterruptedException e) {}
double t = System.nanoTime() - tIni;
time[number] += t;
}
}
public class Triatlon
{
public static void main(String[] args)
{
int runners = 100;
CyclicBarrier Finish_Line_1 = new CyclicBarrier (runners);
Runner c = new Runner(runners, "Triatlon");
ExecutorService e = Executors.newFixedThreadPool(runners);
for (int i=0; i<runners; i++)
e.submit(new Runner(Finish_Line_1, i));
System.out.println(Finish_Line_1.getNumberWaiting()); // this always shows 99
try { int i = Finish_Line_1.await(); }
catch(InterruptedException e01) {}
catch (BrokenBarrierException e02) {}
System.out.println("Swimming phase completed");
// here the rest of the competition, which works the same way
}
}
You have an off-by-one error: you create a CyclicBarrier for 100 threads, but execute 101 awaits, the one-off being in the main method. Due to the semantics of the cyclic barrier, and subject to nondeterministic conditions, your main thread will be the last to execute await, thereby being left alone waiting for another 99 threads to join in.
After you fix this problem, you'll find out that the application keeps running even after all work is done. This is because you didn't call e.shutdown(), so all the threads in the pool stay alive after the main thread is done.
BTW getNumberWaiting always shows 0 for me, which is the expected value after the barrier has been lowered due to 100 submitted threads reaching it. This is nondeterministic, however, and could change at any time.
CyclicBarrier cycles around once all parties have called await and the barrier is opened. Hence the name.
So if you create it with 5 parties and there are 6 calls to await the last one will trigger it to be waiting again for 4 more parties to join.
That's basically what happens here as you have the 1 extra await call in your main. It is waiting for another runners-1 calls to happen.
The simple fix is to create the CyclicBarrier with runners+1 parties.

How to Synchronize Threads

In this multithreading program, when I run it, I always get the output in some random order. But I was wondering if there is any way I can make this program to work in synchronized mode. Like when I runt it then for the first thread it should print out everything, then for second thread it should print out something, then for third thread it should print out everything etc etc. So sample output should be like this for each thread-
Task 1 Started
original: Hello World
Difference:- 0
Task 1 Ended
Task 2 Started
original: Hello World
Difference:- 0
Task 2 Ended
............
............
Task 15 Started
original: Hello World
Difference:- 0
Task 15 Ended
This is my below program. Any suggestions will be appreciated.
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public synchronized void run() {
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public class TestPool {
public static void main(String[] args) throws InterruptedException {
int size = 5; //Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 1; i <= 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
You commented on Jakub's answer as follows:
Can you give me example basis on my code as I just started learning about threading. It will be of great help to me.
What Jakub is saying is that forcing threads to run in a fixed sequence defeats the purpose of using threads in the first place. Think about this.
If you really do want / need your example to run the tasks in order, you may as well do this:
for (int i = 1; i <= 3 * size; i++) {
new ThreadTask(i).run();
}
i.e. just run the runnables in the current thread.
Or you could set the maximum pool size to 1, which forces the service to run the tasks in order. (Of course, this defeats the point of using threads. You won't get any parallelism this way.)
A more sensible approach would be to have each thread return its results in a Future, and then have the main thread fetch the value from each future (in the required order) and print it. Basically, you want to allow the threads to run in any order (and in parallel, if you have multiple cores), but then impose the ordering when you access the results.
The essence of thread is that they can run simultaneously, if you want them to run in order, simply do not use Thread.
There's another kind of requirement, that maybe you want several jobs to work together (simultaneously), but in a given order. In this case, I highly suggest you to implement a queuing system. That is, build a queue like
Queue <C> q
And a thread
class T implements Runnable {
public void run() {
while (!q.empty()) {
// Do something
}
}
}
You can use Runnable through ExecutorService, like the code that you've used.
You can also add some elements into the queue in "Do something" section of previous code, then you can control the order of jobs by yourself.
You can save the the reference to the previous thread and hook up the next thread to the previous one using join(). That will ensure the threads will be run in a series (next one not starting unless the previous one finished). But the point of doing that is eluding me.
public class TestPool
{
static class ThreadTask extends Thread
{
private int id;
private Thread previous;
public ThreadTask(int id, Thread previous){
this.id = id;
this.previous = previous;
}
public void run(){
if(previous != null){
try{
previous.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public static void main(String[] args) throws InterruptedException{
int size = 5; // Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
Thread previous = null;
// queue some tasks
for(int i = 1; i <= 3 * size; i++){
Thread thread = new ThreadTask(i, previous);
previous = thread;
thread.start();
//service.submit(thread);
}
// wait for termination
//service.shutdown();
//service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
Not tested, sry. I don't also know what the ExecutorService is doing, it might break this. Note that I need to be a Thread, being Runnable is not enough. Also, run() needs not be synchronised, as it will be called only once per execution. And you should not start the threads with run(), but with start().
EDIT: I just tried to run it, and the ExecutorService is fu**ing things up. If you just start the thread (like the my code does), then it's working.

Categories

Resources