I'm tracing this code and I'm trying to figure out what exactly it's supposed to do. I can't get it running on IntelliJ. The run option is greyed out even though I defined the Project SDK. But I just want to know what the code is supposed to do.
I just read a bit of theory on threads. Is it just supposed to display each message 100 times with a timestamp on different threads? And Runnable 4 is an example of how to do it with a lambda correct?
Main class
import java.util.Date;
import java.util.concurrent.*;
public class Example02
{
public static void main(String []args)
{
// create runnables
PrintMessageRunnable pmRunnable1 = new PrintMessageRunnable("Runnable 1");
PrintMessageRunnable pmRunnable2 = new PrintMessageRunnable("Runnable 2");
PrintMessageRunnable pmRunnable3 = new PrintMessageRunnable("Runnable 3");
// passing a runnable using Lambda notation
Runnable pmRunnable4 = () -> {
// this is the code inside the run method
String message = "Lambda Runnable";
int REPETITIONS = 100;
int DELAY = 100;
try {
for(int i = 1; i <= REPETITIONS; i++) {
Date now = new Date();
System.out.println(now + ": " + message + "." + i);
Thread.sleep(DELAY);
}
}
catch (InterruptedException e) {
System.out.println("Runnable version interrupted.");
}
};
// specify how many threads the executor service should manage
int MAX_THREADS = 2;
ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS);
// start running
pool.execute(pmRunnable1);
pool.execute(pmRunnable2);
pool.execute(pmRunnable3);
pool.execute(pmRunnable4);
}
}
Print Message Runnable class
import java.util.*;
public class PrintMessageRunnable implements Runnable
{
private String message;
private int REPETITIONS = 100;
private int DELAY = 100;
public PrintMessageRunnable(String message){
this.message = message;
}
public void run(){
try {
for(int i = 1; i <= REPETITIONS; i++) {
Date now = new Date();
System.out.println(now + ": " + message + "." + i);
Thread.sleep(DELAY);
}
}
catch (InterruptedException e) {
System.out.println("Runnable version interrupted.");
}
}
}
In your example you have 2 threads which prints your message with a timestamp.
The lambda presentation of runnable is correct too.
But the usage of java.util.Date is dangerous, bacause of it isn't threadsafe.
Use LocalDateTime in multithread application to avoid errors
Related
I am creating multiple threads and I want each thread to listen for any new message in its BlockingQueue for 2 seconds and then die away. I am using the following code:
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);
ArrayList<String> names = new ArrayList<String>();
names.add("Apple"); names.add("Banana"); names.add("Mango");
HashMap<String, Worker> workermap = new HashMap<String, Worker>();
for (String name: names) {
Worker a_worker = new Worker(queue);
a_worker.setName(name);
a_worker.start();
workermap.put(name, new Worker(queue));
}
queue.put("Hello ");
}
}
class Worker extends Thread {
BlockingQueue<String> q;
Worker(BlockingQueue<String> q) {
this.q = q;
}
public void run() {
try {
long start = System.currentTimeMillis();
long end = start + 2*1000;
while (true) {
String x = q.take();
if(System.currentTimeMillis()>=end){
System.out.println("No new message since two seconds, killing thread " + this.getName());
Thread.interrupted();
// break;
}
// if (x == null) {
// break;
// }
System.out.println(x + "from " + this.getName());
}
} catch (InterruptedException e) {
}
}
}
I expect the output to be like:
Hello from Apple
Hello from Banana
Hello from Mango
No new message since two seconds, killing thread Apple
No new message since two seconds, killing thread Banana
No new message since two seconds, killing thread Mango
But I just get Hello from Apple and then nothing after that. The process keeps on going without any further output. Besides using the timer to kill the thread, I have also tried checking if the queue element is null, but no success. Where am I going wrong?
As already mentioned you need to use pool instead of take() also you can't use Thread.interrupted(); to interrupt a thread. You need to use Thread.currentThread().interrupt();. Also, you do not need to check the time as BlockingQueue#poll do will wait for 2 seconds.
while (!Thread.currentThread().isInterrupted()) {
String x = q.poll(2, TimeUnit.SECONDS);
if (x == null)
System.out.println("No new message since two seconds, killing thread " + this.getName());
Thread.currentThread().interrupt();
System.out.println(x + "from " + this.getName());
}
Output :
No new message since two seconds, killing thread Mango
Hello from Mango
No new message since two seconds, killing thread Apple
nullfrom Apple
No new message since two seconds, killing thread Banana
nullfrom Banana
Edit: However I believe you don't need a loop at all. Simply below code will works fine for you.
public void run() {
try {
String x = q.poll(2, TimeUnit.SECONDS);
if (x == null)
System.out.println("No new message since two seconds, killing thread " + this.getName());
System.out.println(x + "from " + this.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I just tried to do minimal fix on your code:
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);
ArrayList<String> names = new ArrayList<String>();
names.add("Apple"); names.add("Banana"); names.add("Mango");
for (String name: names) {
Worker a_worker = new Worker(queue);
a_worker.setName(name);
a_worker.start();
}
queue.put("Hello");
queue.put("Bonjour");
}
}
class Worker extends Thread {
BlockingQueue<String> q;
Worker(BlockingQueue<String> q) {
this.q = q;
}
public void run() {
long start = System.currentTimeMillis();
long end = start + 2; //just wait for two milliseconds
while (true) {
String x = q.poll();
if(x != null) {
System.out.println(x + " from " + this.getName());
} else if(System.currentTimeMillis() >= end){
System.out.println("No new message since two milliseconds, killing thread " + this.getName());
interrupt();
}
if(interrupted()) {
break;
}
}
}
}
Sample Output:
Hello from Apple
No new message since two milliseconds, killing thread Banana
Bonjour from Mango
No new message since two milliseconds, killing thread Apple
No new message since two milliseconds, killing thread Mango
com.offbynull.coroutines version 1.1.0 consumers only consumes 7500 messages.
Please help me understand why this code only consumes 7500 messages instead of 30000.
public class DemoProducerConsumer {
public static int cnt = 0;
public static final int MAX = 10000;
public static class Producer implements Coroutine {
#Override
public void run(Continuation ctn) throws Exception {
String thName = Thread.currentThread().getName();
System.out.println(thName + ") Producer starting...");
Consumer consumer = new Consumer();
for (int i = 0; i < 3; i++) {
consumer.consume(ctn, "Hello:" + i);
}
System.out.println(thName + ") Producer published 3 messages");
}
}
public static class Consumer {
public void consume(Continuation ctn, String message) {
String thName = Thread.currentThread().getName();
System.out.println(thName + ")" + message);
cnt++; // <<< SUSPECT bug here.
ctn.suspend(); // <<< SUSPECT bug here.
}
}
public static final void main(String... args) throws InterruptedException {
String thName = Thread.currentThread().getName();
System.err.println(thName + ") Preparing Producer ");
new Thread(new Runnable() {
public void run() {
cnt = 0;
Producer producer = new Producer();
CoroutineRunner runner = new CoroutineRunner(producer);
for (int i = 0; i < MAX; i++) {
runner.execute();
}
System.out.println(thName + ") Producer Looped " + MAX + " times.");
}
}).start();
System.err.println(thName + ") Waiting " + (MAX * 3) + " message to be consumed...");
Thread.sleep(10000);
System.err.println(thName + ") Message consumed:" + cnt);
System.err.println(thName + ") Exiting...");
}
}
I plan to use this with Thread Pool to implement a higher performance MVC server.
Separation of consumer and producer is a must.
Author of coroutines here. You seem to be misunderstanding how the execute() method works. Everytime you call suspend(), execute() will return. When you call execute() again, it'll continue executing the method from the point which you suspended.
So, if you want to completely execute your coroutine MAX times, you need to change your main loop to the following:
for (int i = 0; i < MAX; i++) {
boolean stillExecuting;
do {
stillExecuting = runner.execute();
} while (stillExecuting);
}
In addition to that, since you're accessing the field cnt from separate threads, you should probably be marking cnt as volatile:
public static volatile int cnt = 0;
Running with the above changes produces what you expect for your output:
main) Producer Looped 10000 times.
main) Message consumed:30000
main) Exiting...
Also, you should spend some time evaluating whether coroutines are a good fit for your usecase. I don't understand the problem you're trying to solve, but it sounds like normal Java threading constructs may be a better fit.
How to create a cyclic exchange of three threads? That is: first thread must send data to second, second to third and third thread must send data to first.
I wrote some code, but threads exchange in random oder.
class DataClass {
int value;
String message;
DataClass(int v, String s) {
value = v;
message = s;
}
int getValue() {
return (value);
}
String getMassage() {
return (message);
}
}
class Loop implements Runnable {
int counter;
String name;
Exchanger<DataClass> exchanger;
Loop(int startValue, String id, Exchanger<DataClass> ex) {
counter = startValue;
name = id;
exchanger = ex;
System.out.println(name + ": created");
}
public void run() {
System.out.println(name + ": started");
DataClass data = new DataClass(counter, name);
for (int i = 0; i < 3; ++i) {
try {
DataClass newData = exchanger.exchange(data);
counter += newData.getValue();
System.out.println(name + ": from "
+ newData.getMassage() + ": data: "
+ newData.getValue() + ": state = " + counter);
} catch (InterruptedException e) {
System.err.println(e.toString());
}
}
System.out.println(name + ": ended");
}
}
public class ExchangerDemo {
public static void main(String args[]) {
System.out.println("Main process started");
Exchanger<DataClass> exchanger = new Exchanger<DataClass>();
Loop loop1 = new Loop(1, "First", exchanger);
Loop loop2 = new Loop(2, "Second", exchanger);
Loop loop3 = new Loop(3, "Third", exchanger);
new Thread(loop1).start();
new Thread(loop2).start();
new Thread(loop3).start();
System.out.println("Main process ended");
}
}
For your dependency you should make three classes, and have three distinct Exchange objects (one in each). So thread1 would be between 1 and 2 (output of 1 to 2), thread 2's would be between 2 and 3 and thread 3's exhanger would be between itself and 1. Remember the exchanger's would guard only until it had its input from its feeder, to till it passes to its receiver.
Also synchronized is not as bad as the books make out. use it. Watch http://www.youtube.com/watch?v=WTVooKLLVT8
Also for reference Best way of running two threads alternatively?
Also why do you need three threads? Can you use a thread pool and have each task to the 3 things ?
I am using ThreadPoolExecutor in my multithreading program, I want each thread should have particular range of ID's if ThreadSize is set as 10 and Start = 1 and End = 1000 then each thread would have range of 100 id's(basically by dividing end range with thread size) that it can use without stepping on other threads.
Thread1 will use 1 to 100 (id's)
Thread2 will use 101 to 200 (id's)
Thread3 will use 201 to 300 (id's)
-----
-----
Thread10 will use 901 to 1000
I know the logic basically, the logic can be like this-
Each thread gets `N = (End - Start + 1) / ThreadSize` numbers.
Thread number `i` gets range `(Start + i*N) - (Start + i*N + N - 1)`.
As I am working with ThreadPoolExecutor for the first time, so I am not sure where should I use this logic in my code so that each Thread is Using a predefined ID's without stepping on other threads. Any suggestions will be appreciated.
public class CommandExecutor {
private List<Command> commands;
ExecutorService executorService;
private static int noOfThreads = 3;
// Singleton
private static CommandExecutor instance;
public static synchronized CommandExecutor getInstance() {
if (instance == null) {
instance = new CommandExecutor();
}
return instance;
}
private CommandExecutor() {
try {
executorService = Executors.newFixedThreadPool(noOfThreads);
} catch(Exception e) {
System.out.println(e);
}
}
// Get the next command to execute based on percentages
private synchronized Command getNextCommandToExecute() {
}
// Runs the next command
public synchronized void runNextCommand() {
// If there are any free threads in the thread pool
if (!(((ThreadPoolExecutor) executorService).getActiveCount() < noOfThreads))
return;
// Get command to execute
Command nextCommand = getNextCommandToExecute();
// Create a runnable wrapping that command
Task nextCommandExecutorRunnable = new Task(nextCommand);
executorService.submit(nextCommandExecutorRunnable); // Submit it for execution
}
// Implementation of runnable (the real unit level command executor)
private static final class Task implements Runnable {
private Command command;
public Task(Command command) {
this.command = command;
}
public void run() {
// Run the command
command.run();
}
}
// A wrapper class that invoked at every certain frequency, asks CommandExecutor to execute next command (if any free threads are available)
private static final class CoreTask implements Runnable {
public void run() {
CommandExecutor commandExecutor = CommandExecutor.getInstance();
commandExecutor.runNextCommand();
}
}
// Main Method
public static void main(String args[]) {
// Scheduling the execution of any command every 10 milli-seconds
Runnable coreTask = new CoreTask();
ScheduledFuture<?> scheduledFuture = Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(coreTask, 0, 10, TimeUnit.MILLISECONDS);
}
}
Whether this is a good idea or not I will leave it for you to decide. But to give you a hand, I wrote a little program that does what you want... in my case I am just summing over the "ids".
Here is the code:
public class Driver {
private static final int N = 5;
public static void main(String args[]) throws InterruptedException, ExecutionException{
int startId = 1;
int endId = 1000;
int range = (1 + endId - startId) / N;
ExecutorService ex = Executors.newFixedThreadPool(N);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>(N);
// submit all the N threads
for (int i = startId; i < endId; i += range) {
futures.add(ex.submit(new SumCallable(i, range+i-1)));
}
// get all the results
int result = 0;
for (int i = 0; i < futures.size(); i++) {
result += futures.get(i).get();
}
System.out.println("Result of summing over everything is : " + result);
}
private static class SumCallable implements Callable<Integer> {
private int from, to, count;
private static int countInstance = 1;
public SumCallable(int from, int to) {
this.from = from;
this.to = to;
this.count = countInstance;
System.out.println("Thread " + countInstance++ + " will use " + from + " to " + to);
}
// example implementation: sums over all integers between from and to, inclusive.
#Override
public Integer call() throws Exception {
int result = 0;
for (int i = from; i <= to; i++) {
result += i;
}
System.out.println("Thread " + count + " got result : " + result);
return result;
}
}
}
which produces the following output (notice that in true multi-thread fashion, you have print statements in random order, as the threads are executed in whatever order the system decides):
Thread 1 will use 1 to 200
Thread 2 will use 201 to 400
Thread 1 got result : 20100
Thread 3 will use 401 to 600
Thread 2 got result : 60100
Thread 4 will use 601 to 800
Thread 3 got result : 100100
Thread 5 will use 801 to 1000
Thread 4 got result : 140100
Thread 5 got result : 180100
Result of summing over everything is : 500500
I am doing a science fair project in which I am testing how much additional processing cores increase computing speed. This is the multi-core benchmark I have programmed so far, but there are problems. The "thread#.join();" lines all throw errors. Can someone help fix this? Keep in mind I am a beginner so can you please explain in very simple terms how to fix it or show me by putting the repaired code in your response. Here is what I have:
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.text.*;
import java.util.concurrent.*;
public class SciFair
{
/**
* Numa Robertson
* 1/13/11
* Science Fair 2011
*/
public static String now(String dateFormat) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
return sdf.format(cal.getTime());
}
public static void main(String[] args) {
Scanner dataIn = new Scanner(System.in);
DecimalFormat timeInSeconds = new DecimalFormat("##.###");
System.out.println("Are you ready to begin the benchmark? ");
String response = dataIn.nextLine();
double endNum = 0;
if(response.equals("Yes") || response.equals("yes") || response.equals("Ok") || response.equals("ok")) {
System.out.println("Benchmark starting at " + SciFair.now("H:mm:ss:SSS") + ".");
String startTimeHours = SciFair.now("H");
String startTimeMinutes = SciFair.now("mm");
String startTimeSeconds = SciFair.now("ss");
String startTimeMilliseconds = SciFair.now("SSS");
double startTimeHoursNumFormat = Double.valueOf(startTimeHours.trim()).doubleValue();
double startTimeMinutesNumFormat = Double.valueOf(startTimeMinutes.trim()).doubleValue();
double startTimeSecondsNumFormat = Double.valueOf(startTimeSeconds.trim()).doubleValue();
double startTimeMillisecondsNumFormat = Double.valueOf(startTimeMilliseconds.trim()).doubleValue();
double startHoursInSeconds = (startTimeHoursNumFormat * 3600);
double startMinutesInSeconds = (startTimeMinutesNumFormat * 60);
double startMillisecondsInSeconds = (startTimeMillisecondsNumFormat / 1000);
double startTotalSeconds = (startHoursInSeconds + startMinutesInSeconds + startTimeSecondsNumFormat + startMillisecondsInSeconds);
Thread thread1 = new Thread() {
public void run() {
double endNum = 0;
double num = 5832544225416546445465465465465465448412168546725.2655236355335649499923164684654345649874181221173246189579162421579584572121334216957951462175918894199993642446445548521652158975;
for(double numberRun = 0; numberRun <= 1666666660; numberRun++) {
endNum = endNum+((num * 58445246411658545558.458561435435385465146445641894984984651321616548946132131654984 + 26564.6351648941654984156 / 321654984616321654654984365.3216548974165416484 + 216541648165141654.23164584961321316546844651 * 65616484316541486541.1654484646546576746862468546576248645814668585145181 / 111.3216516543464545795479884754424759845 * 3467247954975472171276545789595.4721756147541715715157145715145714514748717521 / 31654688498445132154.3215449848489461531654 * 61654984132165465484464131321145644684.3164846434654648446546546465456465465414321165118547521569845258547566352544 / 32136546465434654654484843131.3164484151515121211554464547951126758178571454164175415417584175664) / 2431276251975915431326725157958456157321624621765419.4321672175951247316726451751487465462645754579517232172757497516373127651975167516715);
}
}
};
Thread thread2 = new Thread() {
public void run() {
double endNum = 0;
double num = 5832544225416546445465465465465465448412168546725.2655236355335649499923164684654345649874181221173246189579162421579584572121334216957951462175918894199993642446445548521652158975;
for(double numberRun = 0; numberRun <= 1666666660; numberRun++) {
endNum = endNum+((num * 58445246411658545558.458561435435385465146445641894984984651321616548946132131654984 + 26564.6351648941654984156 / 321654984616321654654984365.3216548974165416484 + 216541648165141654.23164584961321316546844651 * 65616484316541486541.1654484646546576746862468546576248645814668585145181 / 111.3216516543464545795479884754424759845 * 3467247954975472171276545789595.4721756147541715715157145715145714514748717521 / 31654688498445132154.3215449848489461531654 * 61654984132165465484464131321145644684.3164846434654648446546546465456465465414321165118547521569845258547566352544 / 32136546465434654654484843131.3164484151515121211554464547951126758178571454164175415417584175664) / 2431276251975915431326725157958456157321624621765419.4321672175951247316726451751487465462645754579517232172757497516373127651975167516715);
}
}
};
//Snip out a bunch of copy/paste thread implementations
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
thread5.join();
thread6.join();
String endTimeHours = SciFair.now("H");
String endTimeMinutes = SciFair.now("mm");
String endTimeSeconds = SciFair.now("ss");
String endTimeMilliseconds = SciFair.now("SSS");
double endTimeHoursNumFormat = Double.valueOf(endTimeHours.trim()).doubleValue();
double endTimeMinutesNumFormat = Double.valueOf(endTimeMinutes.trim()).doubleValue();
double endTimeSecondsNumFormat = Double.valueOf(endTimeSeconds.trim()).doubleValue();
double endTimeMillisecondsNumFormat = Double.valueOf(endTimeMilliseconds.trim()).doubleValue();
double endHoursInSeconds = (endTimeHoursNumFormat * 3600);
double endMinutesInSeconds = (endTimeMinutesNumFormat * 60);
double endMillisecondsInSeconds = (endTimeMillisecondsNumFormat / 1000);
double endTotalSeconds = (endHoursInSeconds + endMinutesInSeconds + endTimeSecondsNumFormat + endMillisecondsInSeconds);
double elapsedTime = (endTotalSeconds - startTotalSeconds);
System.out.println("\nThe benchmark is complete at " + SciFair.now("H:mm:ss:SSS") + ", and the end result is " + endNum + ".");
System.out.println("\nThe benchmark was run in " + timeInSeconds.format(elapsedTime) + " seconds.");
} else {
System.out.println("\nPlease restart the program when you are ready to benchmark.");
}
}
}
The problem is that Thread#join() is throwing a checked exception and the compiler wants you to handle that exception. Checked exceptions are typically handled by either stating that your method/function can throw the exception or catching the exception.
In your specific case, since you are just writing a simple benchmarking application, the simplest solution is to just indicate that your code could throw the exception.
public static void main(String[] args) throws InterruptedException {
An example of handling the exception would be something like this:
try {
thread1.join();
thread2.join();
thread3.join();
thread4.join();
thread5.join();
thread6.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); //This is a best practice for handling the InterruptedException only
logger.log("The thread has been interrupted and should now exit quickly and cleanly. Processing may be incomplete.");
}
I suggest you use an ExecutorService. I hope you will see it makes managing threads much easier.
public static void main(String[] args) throws InterruptedException {
int threads = 6;
System.out.println("Benchmark starting at " + new Date());
long start = System.nanoTime();
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < threads; i++)
es.submit(new Runnable() {
public void run() {
// place your benchmark code here
}
});
es.shutdown();
es.awaitTermination(60, TimeUnit.SECONDS);
long time = System.nanoTime() - start;
System.out.printf("%nThe benchmark is complete at " + new Date() + "%nThe benchmark was run in %.3f seconds.%n", time / 1e9);
}
I assume your compile error is that you are not handling InterruptedException. There is no need to catch InterruptedException as a) it shouldn't happen b) you can't do anything but log it.