I'm pretty new using Threads and I just did a little program to understand how it works. As a example a did a prime numbers exercise, the program is running perfectly but what I have discovered is that if I don't use sleep(), the order of the numbers change everytime I press run (without changing the code). So why is happening that?
class Prime extends ThreadDemo implements Runnable
{
public void run()
{
for(int i=2;i<=20;i++)
{
if(prime(i))
{
System.out.printf ("Prime No.= %d \n",i);
}
}
}
}
class notPrime extends ThreadDemo implements Runnable
{
int number= 0;
public void run()
{
prime(number);
}
}
class ThreadDemo
{
public boolean prime(int start_value)
{
for(int i=2; i<start_value; i++)
{
if(start_value%i == 0)
{
System.err.printf ("No. Prime = %d \n", start_value);
return false;
}
}
return true;
}
public static void main(String args[])
{
Prime th1 = new Prime();
Thread childOne = new Thread(th1);
childOne.start();
notPrime th2 = new notPrime();
Thread childTwo = new Thread(th2);
childTwo.start();
}
}
This is the result after I pressed run:
This is the result after pressing again run:
The reason this is happening is that threads run in parallel. When you create a bunch of threads, these threads all start doing things at the same time, and it's a race to see which ones finish first. This isn't deterministic, and sometimes the threads will finish in a different order.
The reason sleep could change this is that sleep will give the threads you created first a head start.
There are two reasons why this happens :
Your prime method is not synchronized.
Even if you synchronize the prime method, you are passing different instances of ThreadDemo to your threads. Locks are obtained on objects. If two threads are passed two different objects of ThreadDemo, each thread will lock its own instance of ThreadDemo thus allowing the Threads to run in parallel.
There are a couple of changes you need to make to your code to make sure that the same ThreadDemo is used for both your threads.
class NotPrimeRunnable implements Runnable {
private ThreadDemo threadDemo;
int number = 0;
public NotPrimeRunnable(ThreadDemo threadDemo) {
this.threadDemo = threadDemo;
}
public void run() {
threadDemo.prime(number);
}
}
class PrimeRunnable implements Runnable {
private ThreadDemo threadDemo;
public PrimeRunnable(ThreadDemo threadDemo) {
this.threadDemo = threadDemo;
}
#Override
public void run() {
for (int i = 2; i <= 20; i++) {
if (threadDemo.prime(i)) {
System.out.printf("Prime No.= %d \n", i);
}
}
}
}
class ThreadDemo {
public synchronized boolean prime(int start_value) {
for (int i = 2; i < start_value; i++) {
if (start_value % i == 0) {
System.err.printf("No. Prime = %d \n", start_value);
return false;
}
}
return true;
}
public static void main(String args[]) {
ThreadDemo runnableTask = new ThreadDemo();
PrimeRunnable th1 = new PrimeRunnable(runnableTask);
Thread childOne = new Thread(th1);
childOne.start();
NotPrimeRunnable th2 = new NotPrimeRunnable(runnableTask);
Thread childTwo = new Thread(th2);
childTwo.start();
}
}
This will fix your problem.
Wikipedia defines thread as: "In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler".
Schedulers are software modules that run in the SO Kernel and manages the processes and threads execution. Schedulers use time-division multiplexing (as in multitasking) algorithms to ensure that all threads and process will be able to execute. One of the scheduler`s characteristics in SOs such as Windows, Mac OS and Linux is that the CPU switches between different software threads. As stated in Wikipedia: "This context switching generally happens frequently enough that the user perceives the threads or tasks as running at the same time."
Based on these considerations, we can explain your software behavior. Non-real time Operating System such as windows and MAC OSx, and many Linux distributions use scheduler algorithms that are non deterministic, so we cant predict the execution order of the threads, then it`s likely every time you execute you are going to get a different result regarding your text output order.
When you use sleep between the threads execution, it seems that the time amount chosen is enough to th1 execute completely before th2 starts. So the output is shown in the correct order.
Related
I am trying to learn multi-threads, and parallel execution in Java. I wrote example code like this:
public class MemoryManagement1 {
public static int counter1 = 0;
public static int counter2 = 0;
public static final Object lock1= new Object();
public static final Object lock2= new Object();
public static void increment1() {
synchronized(lock1) {
counter1 ++;
}
}
public static void increment2() {
synchronized(lock2) {
counter2 ++;
}
}
public static void processes() {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 4; i++) {
increment1();
}
}
});
Thread thread2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 4; i++) {
increment2();
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Counter value is :" + counter1);
System.out.println("Counter value is :" + counter2);
}
public static void main(String[] args) {
processes();
}
}
The code is running properly, but how can I know that the code is running according to time-slicing or whether it is running with parallel execution. I have a CPU with 4 cores. As I understand it, the program should be run with parallel execution, but I am not sure.
The code is running properly, but how can I know that the code is
running according to time-slicing or whether it is running with
parallel execution.
A complete answer to this question would have to cover several factors, but I will be concise and focus mainly on the two most relevant points (IMO) to this question. For simplicity, let us assume that whenever possible each thread (created by the application) will be assigned to a different core.
First, it depends on the number of cores of the hardware that the application is being executed on, and how many threads (created by the application) are running simultaneously. For instance, if the hardware only has a single core or if the application creates more threads than the number of cores available, then some of those threads will inevitably not be executing truly in parallel (i.e., will be mapped to the same core).
Second, it depends if the threads executing their work synchronize with each other or not. In your code, two threads are created, synchronizing using a different object, and since your machine has 4 cores, in theory, each thread is running in parallel to each other.
It gets more complex than that because you can have parts of your code that are executed in parallel, and other parts that are executed sequentially by the threads involved. For instance, if the increment1 and increment2 methods were synchronizing on the same object, then those methods would not be executed in parallel.
Your program is indeed running in parallel execution. In this particular example however you don't need locks in your code, it would run perfectly well without them.
What happens if a thread has been executed same time more than once. Lets say I have thread like
private Runnable mySampleThread() {
return new Runnable() {
#Override
public void run() {
//something is going on here.
}
};
}
And I created an ExecutorService with fixed thread pool of 10. What happens if I execute mySampleThread 10 times in this ExecutorService.
Something like below,
ExecutorService mySampleExecutor = Executors.newFixedThreadPool(10);
while (i <= 10) {
mySampleExecutor.execute(mySampleThread);
i++;
}
Answer is very simple. Executor will execute Runnable object (it's not the Thread object) as described in documentation Interface Executor
Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.
Basically, Executor will pick up one thread of it's internal pool (ThreadPoolExecutor), assign runnable to it a execute run() method.
Firstly elaborate your problem or query.
Nevertheless, assuming that you are calling the method "mySampleThread()" without missing brackets. This method actually returns a new Runnable object every time, so you are passing a new runnable all 10 times to executor. And it means you are submitting 10 different tasks to executor. So if executor creates different thread for every task (that depends upon its implementation), then whatever you code inside run() will be executed 10 times in 10 different threads.
And as described in other answers, the runnable object being passed to executor is not a thread.
Hope it clarifies.
By the way, you may try running the program.
As other answers clearly state, there will be as many new threads as the number of calls (might be less due to used executor, I'm focusing on Runnable reusage, limiting number of threads with executor is well explained in other answers). All of them created with single Runnable object.
What's worth mentioning, and I personally made use of this quite a few times - this is one of the ways to share data between multiple threads as all of these threads share Runnable that was used for creation. Synchronization issues come into play at this point, but that's another story.
Here's code to show the typical usage and the aforementioned synchronization problem.
import java.util.concurrent.ExecutorService;
class MyThread implements Runnable {
public int counter = 0;
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
counter++;
}
}
}
class MySynchronizedThread implements Runnable {
public int counter = 0;
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
synchronized (this) {
counter++;
}
}
}
}
public class RunnableTest {
public static void main(String[] args) throws InterruptedException {
MyThread runnableObject = new MyThread();
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
ex.execute(runnableObject);
}
ex.shutdown();
ex.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out
.println("Without synchronization: " + runnableObject.counter);
MyThread runnableSynchronizedObject = new MyThread();
ExecutorService ex2 = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
ex2.execute(runnableSynchronizedObject);
}
ex2.shutdown();
ex2.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("Without synchronization: "
+ runnableSynchronizedObject.counter);
}
}
There will be no differences in mySampleExecutor.execute(mySampleThread);, mySampleThread method return a new Runnable object. every thread will have it's own Frames
I have hundreds of files to process. I do each file one at a time and it takes 30 minutes.
I'm thinking I can do this processing in 10 simultaneous threads, 10 files at a time, and I might be able to do it in 3 minutes instead of 30.
My question is, what is the "correct" way to manage my 10 threads? And when one is done, create a new one to a max number of 10.
This is what I have so far ... is this the "correct" way to do it?
public class ThreadTest1 {
public static int idCounter = 0;
public class MyThread extends Thread {
private int id;
public MyThread() {
this.id = idCounter++;
}
public void run() {
// this run method represents the long-running file processing
System.out.println("I'm thread '"+this.id+"' and I'm going to sleep for 5 seconds!");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm thread '"+this.id+"' and I'm done sleeping!");
}
}
public void go() {
int MAX_NUM_THREADS = 10;
List<MyThread> threads = new ArrayList<MyThread>();
// this for loop represents the 200 files that need to be processed
for (int i=0; i<200; i++) {
// if we've reached the max num of threads ...
while (threads.size() == MAX_NUM_THREADS) {
// loop through the threads until we find a dead one and remove it
for (MyThread t : threads) {
if (!t.isAlive()) {
threads.remove(t);
break;
}
}
}
// add new thread
MyThread t = new MyThread();
threads.add(t);
t.start();
}
}
public static void main(String[] args) {
new ThreadTest1().go();
}
}
You can use ExecutorService to manage you threads.
And you can add while loop to thread run method to execute file processing task repeatedly.
Also you can read about BlockingQueue usage. I think it will fit perfectly to allocate new files (tasks) between threads.
I would suggest using Camel's File component if you are open to it. The component will handle all the issues with concurrency to ensure that multiple threads don't try to process the same file. The biggest challenge with making your code multi-threaded is making sure the threads don't interact. Let a framework take care of this for you.
Example:
from("file://incoming?maxMessagesPerPoll=1&idempotent=true&moveFailed=failed&move=processed&readLock=none")
.threads(10).process()
So here I write three simple class to inspect how multiple threads working in java, but they produce different result everytime I run it. Here is the code:
public class Accum {
private static Accum a = new Accum();
private int counter = 0;
private Accum(){}
public static Accum getAccum(){
return a;
}
public void updateCounter(int add){
counter+=add;
}
public int getCount(){
return counter;
}
}//end of class
public class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<98; x++){
//System.out.println("Counter in TWO "+a.getCount());
a.updateCounter(1000);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("one " + a.getCount());
}
}//end of class
public class ThreadTwo implements Runnable{
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<99; x++){
//System.out.println("counter in Two "+a.getCount());
a.updateCounter(1);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("two "+a.getCount());
}
public class TestThreaad {
public static void main(String[]args){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}end of class
So the expected result would be : one 98098, two 98099, but it turns out that the results are just unpredictable, sometimes it would be 78000 or 81000, I don't know..
but if i add some code to print a line of current value of count, the final result would be correct..
I really have no idea what is going wrong, and even add the keyword synchronized in the ThreadOne and ThreadTwo, run() method, the problem is still there...
I've studied the java for 3 months and this is the most elusive problem I've ever confronted...so thanks in advance for anyone could help me to understand the basic point of multiple threading...
Code is not synchronized. As it is unsynchonized different Thread trying to update counter might be at same time which cause this problem.
If you synchonized updateCounter then access of this method will be in proper.
public synchronized void updateCounter(int add){
counter+=add;
}
In your example, the Accum instance is shared between the threads. Your update process is a typical READ, COMPUTE-UPDATE, WRITE operation sequence. Because the resource is shared and not protected, those three operations (from two threads -- making six operations) can be interleaved in many different ways, causing updates to be lost.
Here is an example ordering of the operations (number indicates thread):
READ #1 -> reads 10
COMPUTE-UPDATE #1 -> computes 1010
READ #2 -> reads 10
WRITE #1 -> writes 1010
COMPUTE-UPDATE #2 -> computes 11
WRITE #2 -> writes 11 (earlier update is lost)
So you see, almost any result is possible. As #SubhrajyotiMajumder notes, you can use synchronized to fix it. But if you do that, maybe threads aren't right for your problem; or alternatively, you need another algorithmic process.
Your code is not synchronized properly.
As an alternative to a synchronized method I would suggest using AtomicInteger to store the variable accessed and modified from different threads.
I have been trying to solve a problem involving thread communication using wait() and notify(). Basically i have 2 threads T1 and T2 and i want them to be executed in the following order
T1 , T2, T1, T2 ..... How can i achieve that?
Actual Problem: There are 2 threads T1 - which prints odd numbers (say 1 - 100) and T2 - which prints even numbers (1 - 100). Now, the output should be 1, 2, 3, 4 , 5 , .... 100
You describe a Producer-Consumer pattern.
It's java implementations described in numerous java books including M.Grand "Patterns in Java. Volume I" and "Java 2: The Complete Reference" by Naughton and Schildt.
Basic idea: both threads should use 1 monitor (i.e. their code should be inside synchronized(monitor) {} blocks). You also need some flag variable which should indicate which of two threads should work at the moment.
When one of your threads is inside synchronized block it should check flag variable whether it's his turn to do the job. If yes, let it work and then change flag value and then notify all waiting threads. If no, then it should wait.
Look at the java.util.concurrent package, specifically the Exchanger
You're trying to parallelize a multistep process right? If so, see my answer here for an approach and some working code to do that. The answer involves an ExecutorService (or two) and one or more work queues.
For this approach, your processing needs to be able to fit into a Runnable, along with intermediate state information for the processing. You feed each step to the ExecutorService as a Runnable, which will add a second Runnable to perform the next step. This maintains the order of execution, but lets you effectively run as many threads as you wish in parallel.
:EDIT:
As another has suggested, the Exchanger library class can be used for this if you explicitly want to limit processing to 2 threads. I prefer the above approach because it maintains order of execution and allows you to use the modern 4-core (and 8-core) systems fully. It should also reduce synchronization a bit.
If T1 and T2 are 2 different implementations of the Runnable interface, with T1 being a thread that prints just odd numbers (1,3,...) and T2 being one that prints even number (1,2.....), this can be done by using the wait() and notify() methods on a shared monitor. The important thing is for each thread to check for a shared flag before printing its value. The below code works;
//The shared monitor
public class Mutex {
public static boolean oddFlag;
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99)
public class OddPrinter implements Runnable {
private Mutex mutex;
public OddPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: OddPrinter");
int i;
for(i=1; i<100; i+=2 ) {
synchronized (mutex) {
while(!Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(Mutex.oddFlag == true) {
System.out.println("Print from OddPrinter: "+i);
Mutex.oddFlag = false;
mutex.notify();
}
}
}
System.out.println("Finished Thread: OddPrinter: "+i);
}
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98)
public class EvenPrinter implements Runnable {
private Mutex mutex;
public EvenPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: EvenPrinter");
int i;
for(i=2; i<100; i+=2) {
synchronized (mutex) {
while(Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(!(Mutex.oddFlag == true)) {
System.out.println("Print from EvenPrinter: "+i);
Mutex.oddFlag = true;
mutex.notify();
}
}
}
System.out.println("Finished Thread: EvenPrinter: "+i);
}
}
//The test harness that executes the threads
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NumberPrinterTest {
public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newFixedThreadPool(2);
Mutex mutex = new Mutex();
OddPrinter op = new OddPrinter(mutex);
EvenPrinter ep = new EvenPrinter(mutex);
Mutex.oddFlag = true;
es.execute(op);
es.execute(ep);
if(null != es){
es.shutdown();
try {
es.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
Thread.currentThread().interrupted();
}
}
}
}