Java Threads Synchronizing Problem - java

I have the following 2 classes code that produce this result for instance:
Wainting for calculation to complete...
Calculator thread says HELLO!
T1 says that total is 10
Wainting for calculation to complete...
Wainting for calculation to complete...
Now threads are waiting but nobody is going to notify them.
How can I force the threads from T1 to T3 to run before the "Calculator thread" wake em up?
public class Calculator implements Runnable{
private int total;
public int getTotal() {
return total;
}
#Override
public void run() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
total += i;
}
System.out.println(Thread.currentThread().getName() + " says HELLO!");
notifyAll();
}
}
}
import static java.lang.System.out;
public class Reader implements Runnable{
private Calculator c;
public Reader(Calculator calc) {
c = calc;
}
public Calculator getCalculator() {
return c;
}
public static void main(String[] args) {
Calculator calc = new Calculator();
Reader read = new Reader(calc);
Thread thread1 = new Thread(read);
Thread thread2 = new Thread(read);
Thread thread3 = new Thread(read);
thread1.setName("T1");
thread2.setName("T2");
thread3.setName("T3");
thread1.start();
thread2.start();
thread3.start();
Thread calcThread = new Thread(read.getCalculator());
calcThread.setName("Calculator thread");
calcThread.start();
}
}
#Override
public void run() {
synchronized (c) {
try {
out.println("Wainting for calculation to complete...");
c.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println(Thread.currentThread().getName() + " says that " + "total is " + c.getTotal());
}
}
}

This is how I would write the code. Rather than trying to re-invent the wheel with wait/notify I would use concurrency library to do what is needed, a Future.
import java.util.concurrent.*;
public class Main {
static final long start = System.nanoTime();
static void log(String text) {
double seconds = (System.nanoTime() - start) / 1e9;
System.out.printf("%s %.6f - %s%n", Thread.currentThread().getName(), seconds, text);
}
static class Calculator implements Callable<Integer> {
#Override
public Integer call() throws Exception {
int total = 0;
log("calculating total");
for (int i = 0; i < 50000; i++)
total += i;
log("total is " + total);
return total;
}
}
static class Reader implements Callable<Void> {
private final Future<Integer> totalFuture;
public Reader(Future<Integer> totalFuture) {
this.totalFuture = totalFuture;
}
#Override
public Void call() throws ExecutionException, InterruptedException {
log("Waiting for total.");
int total = totalFuture.get();
log("... got total= " + total);
return null;
}
}
public static void main(String... args) {
ExecutorService es = Executors.newCachedThreadPool();
Future<Integer> totalFuture = es.submit(new Calculator());
es.submit(new Reader(totalFuture));
es.submit(new Reader(totalFuture));
es.submit(new Reader(totalFuture));
es.shutdown();
}
}
prints
pool-1-thread-1 0.008154 - calculating total
pool-1-thread-4 0.011356 - Waiting for total.
pool-1-thread-3 0.011292 - Waiting for total.
pool-1-thread-2 0.011128 - Waiting for total.
pool-1-thread-1 0.025097 - total is 1249975000
pool-1-thread-4 0.025351 - ... got total= 1249975000
pool-1-thread-3 0.025372 - ... got total= 1249975000
pool-1-thread-2 0.025380 - ... got total= 1249975000
After
thread3.start();
add the following to wait for the threads to finish.
thread1.join();
thread2.join();
thread3.join();

Thread.join() may seem like an option in this particular situation. Since you have control of the main() function and you know exactly when each thread is starting.
A more general way to handle this situation is use a conditional variable and call the c.wait() within a loop to check the condition variable.
Basically add the isFinished field in the Calculator class :
public class Calculator implements Runnable {
...
public volatile boolean isFinished = false
..
..
Then you replace c.wait() with :
...
while (!c.isFinished) {
c.wait();
}
...
Finally in the `run() method of your Calculator class after calculating total, set the isFinished field
....
for(int i = 0; ....
total = += i;
}
c.isFinished = true
....

U may use Thread.join() method.. I'm not sure how abouts of good programming practices but that will work..

Related

How to cancel all threads after 5 seconds from the main thread with shared memory (shared variable)?

My code:
public class Task3 {
public static void main(String[] args) throws InterruptedException {
ExecutorService poolOfThreads = Executors.newFixedThreadPool(10);
long start = System.currentTimeMillis();
for (int i = 1; i <= 10; i++) {
int finalI = i;
poolOfThreads.submit(new Task2Thread(i, start));
}
poolOfThreads.shutdown();
Thread.sleep(5000);
poolOfThreads.awaitTermination(1, TimeUnit.DAYS);
}
}
public class Task3Thread implements Runnable{
volatile boolean running = true;
private int id;
private long time;
public Task3Thread(int id, long time) {
this.id = id;
this.time = time;
}
#Override
public void run() {
while (running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Thread: " + id + ", time: " + (end - time));
}
}
public void setRunning(boolean running) {
this.running = running;
}
}
These classes spawn 10 threads, each of which every second prints to the console its number and the time elapsed since its launch in milliseconds.
Now I need to cancel all threads after 5 seconds from the main thread with shared memory (shared variable).
How to do it? Tell me please
You can try something like this - store the thread references in an array and after 5 seconds you can fetch the threads one by one from the array and set the running volatile flag to false.
Please check the below modified main method:
Modified code:
public class Task3 {
public static void main(String[] args) throws InterruptedException {
int threadPoolSize = 10;
Task3Thread[] threads = new Task3Thread[threadPoolSize];
ExecutorService poolOfThreads = Executors.newFixedThreadPool(threadPoolSize);
long start = System.currentTimeMillis();
for (int i = 1; i <= 10; i++) {
int finalI = i;
Task3Thread task3Thread = new Task3Thread(i, start);
threads[i-1] = task3Thread;
poolOfThreads.submit(task3Thread);
}
poolOfThreads.shutdown();
Thread.sleep(5000);
for (Task3Thread thread : threads)
{
thread.setRunning(false);
}
}
}

Java - print sequence of numbers using two threads with inter thread communication

I want to print number in the below format. This should be taken care by two thread t1,t2. Can anyone help to enhance the below code which I have written?
First t1 should print 0-4
Then t2 should print 5-9
Then again t1 should print 10-14
Then t2 should print 15-19
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PrintNumber implements Runnable{
String name;
public void run(){
print();
}
synchronized public void print(){
for(int i=0;i< 5;i++){
System.out.println(i+" -- "+Thread.currentThread());
}
}
public static void main(String[] args){
Runnable r = new PrintNumber();
Thread t1 = new Thread(r,"t1");
Thread t2 = new Thread(r,"t2");
t1.start();
t2.start();
}
}
Instead of using the low-level wait() and notify() you can use two Sempaphores.
Each Runnable has a Semaphore it waits for and one it uses to notify the next one.
import java.util.concurrent.Semaphore;
class PrintNumber implements Runnable{
static volatile int nextStartIdx;
private Semaphore waitForSemaphore;
private Semaphore next;
public PrintNumber(Semaphore waitFor, Semaphore next) {
this.waitForSemaphore = waitFor;
this.next = next;
}
public void run(){
while (true) {
print();
}
}
public void print() {
try {
waitForSemaphore.acquire();
int start = nextStartIdx;
for(int i=0;i< 5;i++){
System.out.println(String.format("%d -- %s", i + start, Thread.currentThread().getName()));
}
nextStartIdx += 5;
next.release();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args){
Semaphore a = new Semaphore(1);
Semaphore b = new Semaphore(0);
Thread t1 = new Thread(new PrintNumber(a,b),"t1");
Thread t2 = new Thread(new PrintNumber(b,a),"t2");
t1.start();
t2.start();
}
}
You can use wait and notify to achieve inter thread communication for your sczenario.
class PrintNumber implements Runnable {
String name;
Integer count = 0;
#Override
public void run() {
try {
print();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void print() throws InterruptedException {
while (count < 15) {
for (int i = 0; i < 5; i++) {
count++;
System.out.println(count + " -- " + Thread.currentThread());
}
notifyAll();
wait();
}
}
public static void main(final String[] args) {
final Runnable r = new PrintNumber();
final Thread t1 = new Thread(r, "t1");
final Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
For more information see:
A simple scenario using wait() and notify() in java

Threads Waiting in Line Queue, Java

I'm In a sticky situation. I know this is almost as far as i can get for now, but what i want to do is actually to make an array of thread (or many thread) and accommodate number of threads in queue in the line, so for example i can accommodate 3 thread at a time, i make the first 3 thread run, then make the other wait, when there is free like for example the 1 is free or terminated the other one can start running.
also i want to make sure if the thread can run or not if the thread that is running is the same as the other thread's gender.
Thread myThreads[] = new Thread[LN.GetLine().length()];
int l=LN.GetLine().length();
for (int j = 0; j < LN.GetLine().length(); j++) {
String Name = CR.Gender(LN.GetLine().charAt(j)) + j;
myThreads[j] = new Thread(new MyThread(Name,LN));
myThreads[j].setPriority(l);
System.out.println(myThreads[j].toString());
l--;
}
for(int b=0;b<LN.GetLine().length();b++){
myThreads[b].start();
synchronized(myThreads[b]){
try{
myThreads[b].wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
For now what i can make is accommodate or make 1 thread run at a time.
(Yes this is a Machine bathroom Problem)
My real question is. if i Edit the function run() in myThread() that has a wait() or just plain put a System.out.println(getName() + " is Using");
And how will the thread know in their run() function that other thread is running.
public class MyThread extends Thread {
public MyThread(String id) {
super(id);
}
public void run(){
System.out.println(getName() + " is Using");
>>>Put wait if other thread running<<<<
>>>If can use or not if same gender<<<<
}
Or should i just implement that outside? or put the Waiting outside?
Also i'm really new in Threading so i haven't really explored with Sleep and Interrupt yet.
You can do this without wait.
Here is an example:
public class MyThread extends Thread {
static final Object gender1Lock = new Object();
static final Object gender2Lock = new Object();
int gender;
public MyThread(String id, int gender) {
super(id);
this.gender = gender;
}
public void run(){
System.out.println(getName() + " is waiting");
if(gender == 1){
synchronized(gender1Lock){ // ocupy gender 1
System.out.println(getName() + " is Using");
}
}else if(gender == 2){
synchronized(gender1Lock){ // ocupy gender 2
System.out.println(getName() + " is Using");
}
}
}
}
Since only one thread can synchronize on an object at a time it means that only one thread of a given gender can run at a time. This creates sequential execution of all threads of a given gender.
And here is an example of using this kind of thread.
for(int i = 0; i < 20; i++){
new MyThread("Person " + i, (i%2 == 0) ? 1 : 2).start();
}
... so for example i can accommodate 3 thread at a time, i make the first 3 thread run, then make the other wait, when there is free like for example the 1 is free or terminated the other one can start running.
This can be achieved using a Executor with a fixed Thread Pool.
ExecutorService m = Executors.newFixedThreadPool(3)
ExecutorService f = Executors.newFixedThreadPool(3)
for(;;) {
Object o = new Object();
m.execute(() -> {...; o.wait(); /* You know notify was called on o at this point hence f run clause is running or has just run */ ...})
f.execute(() -> {...; o.notify(); ...})
}
Since this a a batroom the ques are seperate an there will be fixed number of toilets:
ExecutorService m = Executors.newFixedThreadPool(3)
ExecutorService f = Executors.newFixedThreadPool(3)
for(;;) {
Person male = getNextMale();
m.execute(() -> {...; /* do something with male */ ...})
Person female = getNextFemale();
f.execute(() -> {...; /* do something with female */ ...})
}
To implement the queue you can use one of the BlockingQueue implementations.
I would just use two single thread executors obtained via Executors.newSingleThreadExecutor();, one for each gender, and then submit the task to the appropriate executor. Simple and done.
And if you only have one bathroom, then only one executor is needed. For example:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class GetInLine {
public static void main(String[] args) {
List<MyRunnable> myRunnables = new ArrayList<>();
myRunnables.add(new MyRunnable("Bob", false));
myRunnables.add(new MyRunnable("Jill", true));
myRunnables.add(new MyRunnable("Frank", false));
myRunnables.add(new MyRunnable("Amy", true));
myRunnables.add(new MyRunnable("Pete", false));
myRunnables.add(new MyRunnable("Diane", true));
ExecutorService myExecutor = Executors.newSingleThreadExecutor();
for (MyRunnable myRunnable : myRunnables) {
myExecutor.submit(myRunnable);
}
myExecutor.shutdown();
}
}
public class MyRunnable implements Runnable {
private static final int MIN_SLEEP_TIME = 500;
private static final int MAX_SLEEP_TIME = 2000;
private static final int FEMALE_SLEEP_BONUS = 500;
private Random random = new Random();
private String name;
private boolean female;
public MyRunnable(String name, boolean female) {
this.name = name;
this.female = female;
}
public String getName() {
return name;
}
public boolean isFemale() {
return female;
}
#Override
public void run() {
System.out.println(name + " is using");
try {
long sleepTime = MIN_SLEEP_TIME + random.nextInt(MAX_SLEEP_TIME - MIN_SLEEP_TIME);
if (female) {
sleepTime += FEMALE_SLEEP_BONUS;
}
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
System.out.println(name + " is done");
}
}

Multithreaded in java

I have a multithreaded program where I want the one of the thread to print the statement after all the thread finished.How can I do that? and How do I know that all the threads finished?
ExecutorService pool = Executors.newCachedThreadPool();
for(int i = 0; i < myList.size(); ++i) {
pool.execute (new ThreadProcessRunnable (args));
}
public class ThreadProcessRunnable implements Runnable {
public void run() {
System.out.println("last thread should execute this");
}
}
That sounds like an ideal use case for ExecutorService.invokeAll:
ExecutorService pool = Executors.newCachedThreadPool();
List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
for(int i = 0; i < myList.size(); ++i) {
tasks.add (Executors.callable(new ThreadProcessRunnable (args)));
}
List<Future<Object>> futures = pool.invokeAll(tasks);
System.out.println("All tasks finished");
public class ThreadProcessRunnable implements Runnable {
public void run() {
// do some stuff
}
}
invokeAll blocks until all the tasks in the supplied List are complete.
If you absolutely must have the println inside one of the threads' run methods, then the simplest approach I can think of would be to keep some sort of counter in an AtomicInteger
public class ThreadProcessRunnable implements Runnable {
private AtomicInteger taskCounter;
public ThreadProcessRunnable(AtomicInteger counter) {
this.taskCounter = counter;
}
public void run() {
// do stuff
if(taskCounter.decrementAndGet() == 0) {
System.out.println("I am the last thread and I am about to finish");
}
}
}
// Main class
ExecutorService pool = Executors.newCachedThreadPool();
AtomicInteger taskCounter = new AtomicInteger(myList.size());
for(int i = 0; i < myList.size(); ++i) {
pool.execute(new ThreadProcessRunnable(taskCounter));
}
The key thing that makes this work is that taskCounter.decrementAndGet is atomic - if the value of taskCounter is initially 2, for example, and two different threads call decrementAndGet at the same time then it is guaranteed that one thread will see the value 1 and the other thread will see the value 0, so exactly one thread will print the "about to finish" message. This is different from MadProgrammer's answer, which involves a race condition:
latch.countDown();
if(latch.getCount() == 0) { ... }
where it is possible to have thread 1 decrement the value (to 1), then thread 2 decrement it again (to 0), then both threads see the value 0 when they call getCount and both print the message.
This is a REALLY basic example/concept of using a CountDownLatch
public class TestCountDownLatch {
private static CountDownLatch latch;
public static void main(String[] args) {
latch = new CountDownLatch(10);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; ++i) {
pool.execute(new Worker(i));
}
}
public static class Worker implements Runnable {
private int number;
public Worker(int number) {
this.number = number;
}
#Override
public void run() {
try {
System.out.println(number + " is sleeping...");
Thread.sleep((long) (Math.round(Math.random() * 1000)));
} catch (InterruptedException ex) {
}
System.out.println(number + " is Completed...");
latch.countDown();
if (latch.getCount() == 0) {
System.out.println(number + " was last...");
}
}
}
}
Simple Single Thread Test Case
public class TestCountDownLatch {
private static CountDownLatch latch;
public static void main(String[] args) {
latch = new CountDownLatch(1);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 1; ++i) {
pool.execute(new Worker(i));
}
}
public static class Worker implements Runnable {
private int number;
public Worker(int number) {
this.number = number;
}
#Override
public void run() {
try {
System.out.println(number + " is sleeping...");
Thread.sleep((long) (Math.round(Math.random() * 1000)));
} catch (InterruptedException ex) {
}
System.out.println(number + " is Completed...");
latch.countDown();
if (latch.getCount() == 0) {
System.out.println(number + " was last...");
}
}
}
}
You can use a CyclicBarrier with a barrier action (documentation).
Creates a new CyclicBarrier that will trip when the given number of
parties (threads) are waiting upon it, and which will execute the
given barrier action when the barrier is tripped, performed by the
last thread entering the barrier.
You can place it in the main thread. Call pool.await() to block the main thread until all threads in the pool have finished, then do the extra work. The code would look like this:
ExecutorService pool = Executors.newCachedThreadPool();
for(int i = 0; i < myList.size(); ++i) {
pool.execute (new ThreadProcessRunnable (args));
}
pool.shutdown();
pool.awaitTermination();//blocks the main thread
System.out.println("last thread should execute this");

Java - Creating Multiple Threads with a For Loop

I am trying to create multiple threads, the number of which is dependent on the input from the command line. I know extending Thread isn't the best OO practice unless you are making a specialized version of Thread, but hypothetically is this code creating the desired result?
class MyThread extends Thread {
public MyThread (String s) {
super(s);
}
public void run() {
System.out.println("Run: "+ getName());
}
}
class TestThread {
public static void main (String arg[]) {
Scanner input = new Scanner(System.in);
System.out.println("Please input the number of Threads you want to create: ");
int n = input.nextInt();
System.out.println("You selected " + n + " Threads");
for (int x=0; x<n; x++)
{
MyThread temp= new MyThread("Thread #" + x);
temp.start();
System.out.println("Started Thread:" + x);
}
}
}
You have better alternative with ExecutorService
Sample code:
import java.util.concurrent.*;
public class ExecutorTest{
public static void main(String args[]){
int numberOfTasks = Integer.parseInt(args[0]);
ExecutorService executor= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
try{
for ( int i=0; i < numberOfTasks; i++){
executor.execute(new MyRunnable(i));
}
}catch(Exception err){
err.printStackTrace();
}
executor.shutdown(); // once you are done with ExecutorService
}
}
class MyRunnable implements Runnable{
int id;
public MyRunnable(int i){
this.id = i;
}
public void run(){
try{
System.out.println("Runnable started id:"+id);
System.out.println("Run: "+ Thread.currentThread().getName());
System.out.println("Runnable ended id:"+id);
}catch(Exception err){
err.printStackTrace();
}
}
}
Usage:
java ExecutorTest 2
Runnable started id:0
Run: pool-1-thread-1
Runnable ended id:0
Runnable started id:1
Run: pool-1-thread-2
Runnable ended id:1
Related posts: ( Advantages of using ExecutorService as a replacement for plain Thread)
ExecutorService vs Casual Thread Spawner
How to properly use Java Executor?
Yes, it is creating and starting n threads, all ending immediately after printing Run: and their name.
One important thing java JVM can create 20000 thread at a time .
Creating 255 threads in java
class MyThread1 extends Thread {
int k;
public MyThread1(int i) {
k = i;
}
#Override
public void run() {
//Your Code
System.out.println("Thread no. "+k);
}
}
class MainClass {
public static void main(String arg[]) throws UnknownHostException {
Refresh() ;
}
public static void Refresh(){
//create 255 Thread using for loop
for (int x = 0; x < 256; x++) {
// Create Thread class
MyThread1 temp = new MyThread1(x);
temp.start();
try {
temp.join(10);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Another simple example using ExecutorService as recommended by #ravindra-babu
class MyRunnable implements Runnable{
int id;
public MyRunnable(int i){
this.id = i;
}
public void run(){
try{
long init = System.currentTimeMillis();
System.out.println("Start of Thread ID = " + id);
Thread.sleep(id * 1000);
long end = System.currentTimeMillis();
long elapsedTime = end - init;
System.out.println("Elapsed time of Thread ID " + id + ": " + elapsedTime);
} catch(Exception err){
err.printStackTrace();
}
}
}
Then all you need to do is create a new Thread inside the loop
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
try{
ExecutorService executor= Executors.newFixedThreadPool(1);
executor.execute(new MyRunnable(i));
executor.shutdown();
} catch(Exception err){
err.printStackTrace();
return;
}
}
}

Categories

Resources