how to call a method with multiple threads - java

I have a method sendMail(list). This method will send the mails to the recipients which are there in the list.
public void sendMail(List<DTO> dto) {
for(DTO individualObject: dto) {
bulkMailSender.sendSimpleMessage(individualObject.getEmail(),masterDetails.getMailSubject() , content, masterDetails.getMailFrom(), individualObject);
try {
TimeUnit.MINUTES.sleep(Long.parseLong(individualObject.getTimegap().trim()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I have this kind of method. I want to run this method Thread based, when one thread is executing the mails, I should allow the other thread to access sendMail and send simultaneously together. Each and every individualObject contains it's own sleep time.
How can I make it worked with the multiple threads.
Let's take an example
import java.util.concurrent.TimeUnit;
public class SleepClass {
public static void main(String[] args) {
SleepClass s= new SleepClass();
s.m1(10000);
s.m1(20000);
}
public void m1(int time) {
for(int i = 0; i< 3; i++) {
System.out.println(i);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
In the above example I have a regular method and it is executing one by one. How can make it simultaneous execution

if you need simultaneous execution and each time new thread you can find the solution here
public class SleepClass {
public static void main(String[] args) {
SleepClass s= new SleepClass();
s.m2(500);
s.m2(1000);
}
public void m2(int time) {
SleepClass s= new SleepClass();
new Thread(() -> {
s.m1(time);
}).start();
}
public void m1(int time) {
for(int i = 0; i<= 10; i++) {
System.out.println(i);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

You have to put your logic in a Runnable and launch it using new Thread(runnable).start().
To pass parameters to each runnable define them as class variables so you can pass them via the constructor and use them in the run method:
public class SleepClass {
public static void main(String[] args) {
SleepClass s= new SleepClass();
s.m1(10000);
s.m1(20000);
}
public void m1(int time) {
for(int i = 0; i< 3; i++) {
new Thread(new Launcher(i,time)).start();
}
}
public class Launcher implements Runnable {
int i;
int time;
public Launcher(int i, int time) {
this.i=i;
this.time=time;
}
#Override
public void run() {
System.out.println(i);
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Related

print even and odd using 2 threads

Hi I am trying to print even and odd using two threads namedly EvenThread and OddThread, some times I am getting correct result and some times not, could any one please help me.
package com.java8;
public class EvenOddExample {
public static synchronized void print(int i,String name){
System.out.println(i+"--->"+name);
}
public static void main(String[] args) throws InterruptedException {
EvenThread e= new EvenThread();
e.start();
OddThread o=new OddThread();
o.start();
}
public static class EvenThread extends Thread{
public void run() {
for(int i=0;i<10;i++){
if(i%2==0){
print(i,"Even");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static class OddThread extends Thread{
#Override
public void run() {
for(int i=1;i<10;i++){
if(i%2!=0){
print(i,"Odd");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
You need some signaling between the two threads. Putting synchronized on the print method simply guarantees, that only one thread can enter the method at a time. To put your threads into order Object.wait() and Object.notify{All}() methods can be used.
Actually this is some kind of the Sender-Receiver Synchronization Problem. Based on the example of the problem described here (Please read this page in order to understand how this synchronization works) I adapted your code. Additionally I used ExecutorService and Callable instead of extending Thread, which is bad-practice:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddExample {
private static boolean evensTurn = true;
private static Object monitor = new Object();
public static void print(int i, String name) {
System.out.println(i + "--->" + name);
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(new OddCallable());
executorService.shutdown();
}
public static class EvenCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
synchronized (monitor) {
while (!evensTurn) { // not your turn?
monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
}
print(i, "Even");
evensTurn = false; // next odd needs to run
monitor.notifyAll(); // wakeup the odd thread
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
public static class OddCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 1; i < 10; i++) {
if (i % 2 != 0) {
synchronized (monitor) {
while (evensTurn) {
monitor.wait();
}
print(i, "Odd");
evensTurn = true;
monitor.notifyAll();
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
}
synchronized is used to lock the access of another thread, when the locked object is free, it does not guarantee which is next called thread. You can use semaphore to make inter-thread communication:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
#Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
#Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}

Another way to perform multithreading than using static method and variable

I'm writing a program that starts 1000 threads, each thread adds 1 to a variable sum. here's the code:
public class Test1 implements Runnable{
public Test1( ) {
}
public void run() {
Sum.sum++;
}
public static void main(String[] args) {
//Sum s = new Sum();
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(new Test1());
try {
t.start();
t.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Sum.getSum());
}
}
public class Sum {
static int sum;
public Sum() {
sum = 0;
}
public static int getSum() {
return sum;
}
public static void setSum(int sum) {
sum = sum;
}
}
Is there a way that creates an instance of the Sum class, then each thread adds 1 to the same instance of the Sum class? I mean not using a static method or variable.
public class Test1 implements Runnable{
Sum s = null;
public Test1(Sum s) {
this.s = s;
}
public void run() {
s.sum++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Sum s = new Sum();
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(new Test1(s));
t.start();
}
System.out.println(s.getSum());
}
}
class Sum {
int sum;
public Sum() {
sum = 0;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
sum = sum;
}
}
Important notes :
1 - sleep() is static, so it acts on the current running thread, so if you meant to sleep thread t, the correct way to do it is as in the answer
2- System.out.println(s.getSum()); isn't guaranteed to run after all threads finish .... If you want to do so, use ExecutorService
3- do your synchronized add() method instead of accessing the variable directly .... here it wont matter much, but in real life example, you might encounter race condition

Why is the ArrayList not updated in the following example?

I am using the JNativeHook library.
An instance of GlobalKeyListener starts listening to Keystrokes and adds them to arrayList1; problem is that the arrayList1 does not seem to get updated (list1itemCount does never get bigger then 0) when accessing it over the infinite while(true) loop in the Child class. Why is that and what must I do to achieve that?
public class Child {
public static void main(String[] args) {
// Get the logger for "org.jnativehook" and set the level to warning.
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalKeyListener globalkeylistener = new GlobalKeyListener();
GlobalScreen.addNativeKeyListener(globalkeylistener);
Connection conn;
while(true){
int list1itemCount = globalkeylistener.arrayList1.size();
if (list1itemCount >= 4)
System.out.println(list1itemCount);
}
}
}
GlobalKeyListener Class:
public class GlobalKeyListener implements NativeKeyListener {
ArrayList<Class1> arrayList1 = new ArrayList<>();
public ArrayList<Class1> listing() {
return arrayList1;
}
public void nativeKeyPressed(NativeKeyEvent e) {
arrayList1.add(new Class1(e.getKeyCode(), 1));
}
public void nativeKeyReleased(NativeKeyEvent e) {
arrayList1.add(new Class1(e.getKeyCode(), 0));
}
public void nativeKeyTyped(NativeKeyEvent e) {
}
}
This is a multithreading issue. The keyEvent updates occur on a different thread, and your while(true) won't update. Also, the ArrayList itself is not threadsafe as you've written it.
It would be better to synchronize on something (the easiest, not necessarily best) thing is the key listener itself, and have it wait until the update occurs and then notify. Here's the modified code:
GlobalKeyListener.java
public class GlobalKeyListener implements NativeKeyListener {
ArrayList<Class1> arrayList1 = new ArrayList<>();
public ArrayList<Class1> listing() {
return arrayList1;
}
public void nativeKeyPressed(NativeKeyEvent e) {
synchronized(this) {
arrayList1.add(new Class1(e.getKeyCode(), 1));
this.notifyAll();
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
synchronized(this) {
arrayList1.add(new Class1(e.getKeyCode(), 0));
this.notifyAll();
}
}
public void nativeKeyTyped(NativeKeyEvent e) {
}
}
Child.java
public class Child {
public static void main(String[] args) throws InterruptedException {
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalKeyListener globalkeylistener = new GlobalKeyListener();
GlobalScreen.addNativeKeyListener(globalkeylistener);
synchronized(globalkeylistener) {
while(true){
int list1itemCount = globalkeylistener.arrayList1.size();
if (list1itemCount >= 4) {
System.out.println(list1itemCount);
}
globalkeylistener.wait();
}
}
}
}

Producer consumer variant java BlockingQueues

I'm working on a variant of the producer consumer problem in Java. I have a producer thread creating objects, that are put into an priority blocking queue, and then passed into the main container, the controller, which is a bounded buffer.
The reason for the queue is that when the main container has a certain % of Object A, it will only accept objects of type B, and some other scenarios that we have been asked to look at.
I'm having trouble figuring out what is going wrong with the code, the debugger is just jumping from in.offer in InQueue, and in.push in Producer. Any direction or advice would be appreciated.
import java.util.concurrent.PriorityBlockingQueue;
public class InQueue implements Runnable {
Controller c;
private PriorityBlockingQueue in;
public InQueue(Controller c) {
this.c = c;
in = new PriorityBlockingQueue();
}
public void push(C c) {
in.offer(c);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
C temp = (C) in.take(); //will block if empty
c.arrive(temp);
} catch (InterruptedException e) {} // TODO
}
}
}
public class Controller {
private BoundedBuffer buffer;
private int used;
Controller(int capacity) {
this.buffer = new BoundedBuffer(capacity);
used = 0;
}
public void arrive(C c) {
try {
buffer.put(c);
used++;
} catch (InterruptedException e) { } //TODO
}
public C depart() {
C temp = null; //BAD IDEA?
try {
temp = (C)buffer.take();
used--;
} catch (InterruptedException e) { } //TODO
return temp; //could be null
}
}
Your code is not compiling because of the wrong way your using generics. Another thing is that there is no default implementation of BoundedBuffer. Below I made a working implementation for the producer - consumer problem below with blocking queues. Have a look and correct your mistakes.
package concurrency;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Producer<T> {
private final BlockingQueue<T> queue;
private final Consumer consumer;
private static volatile boolean isShutdown;
private final static Object lock = new Object();
public Producer() {
this.queue = new LinkedBlockingQueue<T>();
this.consumer = new Consumer();
}
public void start() {
consumer.start();
}
public void stop() {
synchronized (lock) {
isShutdown = true;
}
consumer.interrupt();
}
public void put(T obj) throws InterruptedException {
synchronized (lock) {
if (isShutdown)
throw new IllegalStateException("Consumer Thread is not active");
}
queue.put(obj);
}
private class Consumer extends Thread {
public void run() {
while (true) {
synchronized (lock) {
if (isShutdown)
break;
}
T t = takeItem();
// do something with 't'
if(t!=null)
printItem(t);
}
}
private void printItem(T t) {
System.out.println(t);
}
private T takeItem() {
try {
return queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return null;
}
}
public static void main(String[] args) throws InterruptedException {
Producer<Integer> producer = new Producer<Integer>();
producer.start();
for (int i = 0; i <20; i++) {
producer.put(i);
if (i >= 7)
Thread.sleep(500);
}
producer.stop();
}
}

Concurrency - why does the last instruction in this function never execute?

I have this code:
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
Where the calling class implements a method that calls notifyAll() on synchObj when WorkerThread instance is done. Everything works pretty much as expected except the final call to System.out.println("End"); is never called. Why is that?
Edit: Here's the rest of the code:
public class App implements Notifee {
private boolean isDone = false;
private final Object synchObj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
App app = new App();
for (int i = 0; i < 5; i++) {
try {
app.doSomething();
} catch (InterruptedException e) {
System.err.println("Didn't even start");
e.printStackTrace();
}
}
}
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
#Override
public void letMeKnow() {
synchronized (synchObj) {
synchObj.notifyAll();
}
}
}
public class WorkerThread extends Thread {
private Notifee n;
public WorkerThread(Notifee n){
this.n = n;
}
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
n.letMeKnow();
}
}
You are never setting isDone to true. Also you should make it volatile. You probably should add:
#Override
public void letMeKnow() {
isDone = true;
synchronized (synchObj) {
synchObj.notifyAll();
}
}
Edit: If you want to just wait for the worker thread to finish call:
w.join();

Categories