Multithreading example for x number of threads - java

I am new to Multithreading world, I am not sure how should I write a java application that can invoke x number of threads, if we pass x number of threads from the command prompt. Just Like if we are passing
java –jar pds_client_batch.jar <number of threads>
and here if number of threads is passed as 20 then it should run for twenty threads. Any simple example will be appreciated.

public class Example
{
private class DumbThread implements Runnable
{
public void run()
{
System.out.println("Thread ran");
}
}
public static void main(String args[])
{
int input = Integer.parseInt(args[0]);
for (int x = 0; x < input; x++)
new Thread(new DumbThread()).start();
}
}
Now, if you want it to do something useful...
Edit: made more complete. It still does nothing useful. Also it doesn't do even basic error checking.

You could also you an executorService like ThreadPoolExecutor. and pass in the number of threads you want it to use.

Nowadays you are encouraged to use thread pools for better management of threads. You can create a fixed thread pool:
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public void run() {
System.out.println("I am task " + id);
}
}
public class TestPool {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 0; i < 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}

Related

Can we implement a coroutine type of functionality in Java?

I am trying to see if there anyway a single thread in Java can switch between tasks where each task is an infinite loop ?
I have the following code and I am wondering if there is any possible way I could make the count for all three jobs below change while they run on single thread? perhaps using wait/notify?
I was able to change the count only for one job but not for all three jobs.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Job implements Runnable {
protected int count;
public Job(){
this.count = 0;
}
public void run() {
System.out.println(Thread.currentThread().getName());
while(true) {
this.count = this.count + 1;
System.out.print("");
}
}
}
public class ThreadTest {
static int tasks = 3;
static Job[] jobs = new Job[3];
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < tasks; i++) {
jobs[i] = new Job();
executor.execute(jobs[i]);
}
while (!executor.isTerminated()) {
for (int i = 0; i < tasks; i++) {
System.out.print(jobs[i].c + " ");
}
System.out.println();
try { Thread.sleep(1000); } catch (InterruptedException ex) { }
}
System.out.println("end");
}
}
The reason your current code doesn't work can be found in the documentation:
If additional tasks are submitted when all threads are active, they
will wait in the queue until a thread is available
Your first Job is running forever and so the other Jobs are never taken off the queue.
One way to solve this would be by having each Job add itself to the back of the queue once it's completed one iteration. This allows other items in the queue to be given time to execute:
class Job implements Runnable {
protected int count;
private final ExecutorService executor;
public Job(ExecutorService executor){
this.count = 0;
this.executor = executor;
}
public void run() {
System.out.println(Thread.currentThread().getName());
this.count = this.count + 1;
System.out.print("");
executor.execute(this);
}
}
And you'd need to change
new Job();
to
new Job(executor);
No: when a thread is allocated to a task, it executes the run() method. When the run method returns or when there is an exception, the next task will be allocated to the thread.

Loop in multiple Threads

right now i'm trying to get my head arround threads and concurrency,
so i tried to make multiple threads which counts together to 1000.
Example: Thread 1=0, Thread 2=1.Thread 3=2, and so on
As you will see in the code i implemented the Runnable interface and started the threads.
What i can see is that every thread starts the loop only for itself even if i use a synchronized method.
This is the loop "class"
private String threadname;
private int counter;
Task3(String threadname,int counter) {
this.threadname = threadname;
this.counter =counter;
}
private synchronized void compute(int i) {
try {
// "simulate" computation
System.out.println(threadname);
Thread.sleep(100);
System.out.println(" " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
for(int i=0; i <= counter;i++)
compute(i);
}
and in this class i start 4 threads with a for loop and give the method aboce the parameters which is only the thread name and how often they should count...
for(int i=0; i<=3;i++){
Runnable r =new Thread(new Task3("Thread"+i,1000));
Thread t = new Thread(r);
t.start();
}
thanks in advance
Explanation
Synchronized only means that it is ensured that a thread waits before entering the method until another thread has finished executing this method. This means that only one thread, at one time, can be inside of this synchronized method.
This can prevent strange behavior when using non-atomic operations. For example threads catching outdated values, thinking they would be up-to-date.
Solution
If you want that all threads count together you need some kind of shared resource, i.e. the counter. Currently every thread has his own counter. You need one counter in total which is shared among all threads.
A quick and dirty method would be to make the counter static. But you can probably do better with a design like this:
Class which manages the threads:
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
for (int i = 0; i < 3; i++) {
Counter counter = new Counter(demo, 1000);
counter.start();
}
}
// Provide a shared resource for all threads
private int sharedCounter = 0;
// Provide a count method for all threads
// which is synchronized to ensure that no
// strange behavior with non-atomic operations occurs
public synchronized void count() {
sharedCounter++;
}
}
And the Thread class:
public class Counter extends Thread {
private Demo mDemo;
private int mAmount;
public Counter(Demo demo, int amount) {
// Remember the shared resource
mDemo = demo;
mAmount = amount;
}
#Override
public void run() {
for (int i < 0; i < mAmount; i++) {
// Call the count method provided
// by the shared resource
mDemo.count();
// Sleep some millis
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Print alternately with three threads [duplicate]

I am trying to print numbers from 1 to 10 using three threads. thread 1 prints 1, 2 prints 2, 3 prints 3, 4 is printed by thread 1 again and so on.
I have created a shared printer resource that helps those threads to print number. But I am getting confused as how can i make the number to be visible by all threads.
The problem is eachthread is seeing their own copy of number while I need the same number to be shared by all threads.
I am trying to create this example for learning purposes. I have seen other pages on SO that had same kind of problem but I am not able to get the concept.
Any help is appreciated.
how is this example diffrent from what I am doing?
Printing Even and Odd using two Threads in Java
public class PrintAlternateNumber {
public static void main(String args[]) {
SharedPrinter printer = new SharedPrinter();
Thread t1 = new Thread(new myRunnable2(printer,10,1),"1");
Thread t2 = new Thread(new myRunnable2(printer,10,2),"2");
Thread t3 = new Thread(new myRunnable2(printer,10,3),"3");
t1.start();
t2.start();
t3.start();
}
}
class myRunnable2 implements Runnable {
int max;
SharedPrinter printer;
int threadNumber;
int number=1;
myRunnable2(SharedPrinter printer,int max,int threadNumber) {
this.max=max;
this.printer=printer;
this.threadNumber=threadNumber;
}
#Override
public void run() {
System.out.println(" The thread that just entered run "+ Thread.currentThread().getName());
for(int i =1;i<max;i++){
try {
printer.print(i,threadNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SharedPrinter {
boolean canPrintFlag=false;
public synchronized void print(int number,int threadNumber) throws InterruptedException{
if(number%3==threadNumber) {
canPrintFlag=true;
}
while(!canPrintFlag)
{
System.out.println(Thread.currentThread().getName() + " is waiting as it cannot print " + number);
wait();
}
System.out.println(Thread.currentThread().getName()+" printed "+number);
canPrintFlag=false;
notifyAll();
}
}
//output
//The thread that just entered run 2
// The thread that just entered run 3
//The thread that just entered run 1
//3 is waiting as it cannot print 1
//1 printed 1
//1 is waiting as it cannot print 2
//3 is waiting as it cannot print 1
//2 is waiting as it cannot print 1
Technique second
it is still incomplete but I am close
output
0printed by0
2printed by2
1printed by1
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class AlternateNumber {
public static void main(String args[]) {
printerHell ph = new printerHell();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i=0;i<10;i++)
{
queue.add(i);
}
Thread t1 = new Thread(new myRunnableHell(queue,0,ph),"0");
Thread t2 = new Thread(new myRunnableHell(queue,1,ph),"1");
Thread t3 = new Thread(new myRunnableHell(queue,2,ph),"2");
t1.start();
t2.start();
t3.start();
}
}
class myRunnableHell implements Runnable {
BlockingQueue<Integer> queue;
int threadNumber;
printerHell ph;
myRunnableHell(BlockingQueue<Integer> queue, int threadNumber,printerHell ph) {
this.queue=queue;
this.threadNumber=threadNumber;
this.ph=ph;
};
int currentNumber;
#Override
public void run() {
for(int i=0;i<queue.size();i++)
{
currentNumber=queue.remove();
if(threadNumber%3==currentNumber)
{
ph.print(currentNumber);
}
}
}
}
class printerHell {
public synchronized void print(int Number)
{
System.out.println(Number + "printed by" + Thread.currentThread().getName());
}
}
Please see my solution here..
Using simple wait/notify
https://stackoverflow.com/a/31668619/1044396
Using cyclic barriers:
https://stackoverflow.com/a/23752952/1044396
For your query on 'How different it is from even/odd thread problem.
--> it is almost same ... instead of maintaining two states have one more state to call the third thread, so I believe,this can be extended any number of threads.
EDIT:
You may view this approach when you want to have 'n' number of threads to do the work sequentially.(Instead of having different classes t1,t2,t3 etc)
https://codereview.stackexchange.com/a/98305/78940
EDIT2:
Copying the code here again for the above solution
I tried to solve using a single class 'Thrd' which gets initialized with its starting number.
ThreadConfig class which as size of total number of threads you want to create.
State class which maintains the state of the previous thread.(to maintain ordering)
Here you go..(please review and let me know your views)
EDIT:
How it works -->
when a thread Tx gets a chance to execute.. it will set state variable's state with x. So a next thread(Tx+1) waiting , will get a chance once state gets updated. This way you can maintain the ordering of threads.
I hope i am able to explain the code. Please run it and see or let me know for any specific queries on the below code
1)
package com.kalyan.concurrency;
public class ThreadConfig {
public static final int size = 5;
}
2) package com.kalyan.concurrency;
public class State {
private volatile int state ;
public State() {
this.state =3;
}
public State(int state) {
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
3) package com.kalyan.concurrency;
public class Thrd implements Runnable {
int i ;
int name;
int prevThread;
State s;
public Thrd(int i,State s) {
this.i=i;
this.name=i;
this.prevThread=i-1;
if(prevThread == 0) prevThread=ThreadConfig.size;
this.s=s;
}
#Override
public void run() {
while(i<50)
{
synchronized(s)
{
while(s.getState() != prevThread)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==prevThread)
System.out.println("t"+ name+ i);
s.setState(name);
i = i +ThreadConfig.size ;
s.notifyAll();
}
}
}
}
4)
package com.kalyan.concurrency;
public class T1t2t3 {
public static void main(String[] args) {
State s = new State(ThreadConfig.size);
for(int i=1;i<=ThreadConfig.size;i++)
{
Thread T = new Thread(new Thrd(i,s));
T.start();
}
}
}
OUTPUT:
t11
t22
t33
t44
t55
t16
t27
t38
t49
t510
t111
t212
t313
t414
t515
t116..............
I hope I understood you right, but there are to main "features" in java to make a variable being shared between threads:
the volatile keyword
volatile int number = 1;
AtomicInteger (a standard java class -> no library)
AtomicInteger number = new AtomicInteger(1);
These two techniques should both do what you want, however I have no experience using it, I just came upon this word, didn't know what it means and did some digging.
Some stuff to read: ;)
volatile for java explained --> http://java.dzone.com/articles/java-volatile-keyword-0
a better explanation (with IMAGES!!) but for c# (which is still the same usage) --> http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
And a link to some usages of AtomicInteger --> https://stackoverflow.com/a/4818753/4986655
I hope I could help you or at least send you in the right direction :)
- superfuzzy

Cannot force a simple 'race condition' when extending Thread, only when using ExecutorService

I am working through Bruce Eckel's Thinking in Java 4th edition.
In the chapter on concurrency there is an exercise on race conditions, when they might occur and how to prevent them.
Unfortunately I cannot seem to replicate the race condition when extending a simple Thread, but using the same code in a Runnable and an ExecutorService I do get the race condition.
Can anyone explain the difference?
My basic class which must always be even:
class EvenNumber {
private int value=2;
public int getValue(){
return value;
}
public boolean validate(){
if (value%2 !=0) {
System.err.println(value + " is not an even number!");
throw new RuntimeException();
}
return true;
}
protected void addTwo(){
++value;
Thread.yield(); //problem should occur here
++value;
}
//public mutator
public void addLotsOfTwos(int n){
for(int i=0;i<n;i++){
addTwo();
}
}
}
Extending a thread I can't seem to be able to get a race condition going.
class EvenCheckerThread extends Thread {
private static int counter =0;
private final int id;
private EvenNumber even;
EvenCheckerThread(EvenNumber even){
this.id = ++counter;
this.even = even;
}
public void run(){
System.out.println("Start thread#" + id + "using " + even);
for(int i=0; i<10 ;i++){
even.addLotsOfTwos(10);
even.validate();
}
System.out.println("Finish thread#" + id);
}
}
Exactly same code in a Runnable quickly throws an exception:
class EvenCheckerRunnable implements Runnable {
private static int counter =0;
private final int id;
private EvenNumber even;
EvenCheckerRunnable(EvenNumber even){
this.id = ++counter;
this.even = even;
}
public void run(){
System.out.println("Start thread#" + id + "using " + even);
for(int i=0; i<10 ;i++){
even.addLotsOfTwos(10);
even.validate();
}
System.out.println("Finish thread#" + id);
}
}
I try and test my classes from E11.main(). However, passing the same EvenNumber object to the Thread doesn't give me an exception even though I've created 100 threads, they all seem to start and finish nicely in order.
Creating 10 threads using Executors quickly throws an exception.
public class E11 {
public static void main(String[] args) {
EvenNumber even = new EvenNumber();
for(int i=0;i<100;i++){
new EvenCheckerThread(even).run();
}
/*ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
exec.execute(new EvenCheckerRunnable(even));
}*/
}
}
I'm sure I've misunderstood something at a very basic level, but I don't know what...
This piece of code:
for(int i=0;i<100;i++){
new EvenCheckerThread(even).run();
}
does not run the code in new Thread, so everything gets properly executed in one single sequence. You created an instance of the class Thread, but the run() method simply executes on the current Thread. Instead, try to call the start() method to actually start a new Thread.:
for(int i=0;i<100;i++){
new EvenCheckerThread(even).start();
}

How to throttle method invocations to allow threads to complete

I currently have the following setup. I am getting out fo memory exceptions after it runs for a little while; I suspect the for loop in main is causing too much of a backup method calls. What is the best way to throttle the calls if I don't wish to increase the thread pool size?
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// method body using i
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 1000000000; ++i)
myMethod(i);
}
}
EDIT
I meant to show that I am passing in the index for the loop to the runnables.
You have ten threads so add ten jobs and you will never run out of memory trying to schedule them.
e.g.
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// do every tenth task.
for(int j = i; j < 1000000000; j += 10) {
// method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}
I am getting out fo memory exceptions after it runs for a little while; I suspect the for loop in main is causing too much of a backup method calls. What is the best way to throttle the calls if I don't wish to increase the thread pool size?
This is a FAQ. See my answer here: Process Large File for HTTP Calls in Java
You need to define your own bounded job queue and then define a RejectedExecutionHandler. The following code will block when it tries to add more than 100 jobs to the job queue.
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});
i would go with this (it will allow each worker to perform same amount of work in terms of cpu clocks)
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
final static AtomicInteger counter = new AtomicInteger(0);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
while (counter.getAndIncrement() < 1000000000) {
//method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}
or do increments of 10 in each worker as Peter suggested. Saves a lot of objects and processing speed is high.

Categories