I'm a little confused about the difference between threading and multi-threading in Java as far as syntax. I need to write a program to print even numbers 0 to 30 and then odds using threading and another program to do the same thing using multi-threading. I wrote a program that runs and does what it's supposed to but I don't know whether it's threading or multi-threading, or how to go about doing the one it isn't. Here is my program-
public class OddEven extends Thread {
public static void main(String args[]){
Runnable r1 = new Runnable1();
Thread t1 = new Thread(r1);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=0; i<=30; i+=2) {
System.out.println(i);
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(int i=1; i<=30; i+=2){
System.out.println(i);
}
}
}
Would this program be considered just a single thread?
public class OddEven {
public static void main(String args[]){
for(int i=0; i<=30; i+=2) {
System.out.println(i);
}
for(int i=1; i<=30; i+=2){
System.out.println(i);
}
}
}
Multithreading enables you to do multiple works simultaneously.
For example, if you make a game in which a boy moves forward & goes on firing as well. If you use single threading system, then either a boy could move forward or can fire on his enemy at a time. He cant do the both the works simultaneously.
In your case, when you call t1.start();, then a new thread gets started which will execute your Runnable1's method. Then you called t2.start();, immediately, it will also another thread gets started & your Runnable2's method will gets executed.
Both the method will get executed simultaneously. If you don't use multi threading, then only after finishing the first loop, the next loop will get start.
Multi-threading mainly use in the programs where main thread may process for a long time & you want to use other functions of the program.
Hope this helps!!!!
Related
This question already has answers here:
What does 'synchronized' mean?
(17 answers)
Closed 1 year ago.
I was practicing multithreading in java and wrote the below code
class Printer {
synchronized void printHi(String x) {
System.out.println(x);
}
}
class MyThread extends Thread {
Printer objm;
MyThread(Printer a) {
objm = a;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
objm.printHi("MyThread" + i);
}
}
}
class YourThread extends Thread {
Printer objy;
YourThread(Printer a) {
objy = a;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
objy.printHi("YourThread" + i);
}
}
}
public class test {
public static void main(String[] args) {
Printer ob = new Printer();
MyThread mt = new MyThread(ob);
YourThread yt = new YourThread(ob);
mt.start();
yt.start();
}
}
Sometimes I gets the output as:
MyThread0
YourThread0
MyThread1
YourThread1
MyThread2
YourThread2
MyThread3
YourThread3
YourThread4
MyThread4
MyThread5
MyThread6
YourThread5
MyThread7
YourThread6
MyThread8
MyThread9
YourThread7
YourThread8
YourThread9
Which is asynchronous. Why is it so even after making the function printHi() as synchronized?
Synchronized means only one thread can be running a block of code marked synchronized on the same lock object (instance of the object for the case of a synchronized method). It does not mean threads will run in order. It is perfectly correct for the two threads to enter those synchronized blocks in any order, and any number of times before the next thread does. What you want is much more difficult and beyond what a simple synchronized block can do.
If you want it to always go Thread A, Thread B, Thread A, Thread B- first I'd question that those two things should actually be separate threads. Wanting things to run sequentially like that is the number one sign you aren't asynchronous and shouldn't be multiple threads. But if they do, you're probably best off with two threads with message handlers, sending messages to each other about when they're allowed to run. Or using semaphores to signal each other. It's hard to give exact advice because the problem here is obviously a trivialized version of something harder, and without the details the right implementation is hard to guess.
You're synchronizing the printHi function call. That means two instances of printHi on the same object won't run at the same time. That's great. It means you'll never get output like
MyThYourThreadread77
(Side note: Java's printing primitives are already somewhat synchronized if I recall correctly, so that shouldn't happen anyway. But for demonstrative purposes, it'll do)
However, your loop is not synchronized. If you want the whole loop to only happen in one thread at a time, remove synchronized from print and write your loop as
synchronized (objm) {
for (int i = 0; i < 10; i++) {
objm.printHi("MyThread" + i);
}
}
(and the same for objy in YourThread)
There's still no guarantee on which one will happen first, but the two loops won't interrupt each other in this case.
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.
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'm trying to get started with learning threading in Java and here's a simple example that I tried from here
Here's my code :
A simple main class:
package com.vogella.Thread;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// We will store the threads so that we can check if they are done
List<Thread> threads = new ArrayList<Thread>();
// We will create 500 threads
for (int i = 0; i < 500; i++) {
Runnable task = new MyRunnable(10000000L + i);
Thread worker = new Thread(task);
// We can set the name of the thread
worker.setName(String.valueOf(i));
// Start the thread, never call method run() direct
worker.start();
// Remember the thread for later usage
threads.add(worker);
}
int running = 0;
do {
running = 0;
for (Thread thread : threads) {
if (thread.isAlive()) {
running++;
}
}
System.out.println("We have " + running + " running threads. ");//-A
} while (running > 0);
}
}
and the MyRunnable class is as follows :
package com.vogella.Thread;
public class MyRunnable implements Runnable {
private final long countUntil;
MyRunnable(long countUntil) {
this.countUntil = countUntil;
}
#Override
public void run() {
long sum = 0;
for (long i = 1; i < countUntil; i++) {
sum += i;
}
System.out.println(sum);
System.out.println("Test123");
}
}
And this is my output
49999995000000
Test123
50000005000000
Test123
50000015000001
Test123...
However I dont understand why the line marked with comment A in Main.java never prints. Any insight on this would be helpful.
Thanks!
It should print. Check you're not missing it in the program output.
Try commenting out the println()'s in your Runnable
There are a few things wrong with that code in terms of best practices. Unless that site mentions them (too lazy to look), I might consider finding a different tutorial. Also, have you checked the entire output? It's probably printing. It is not guaranteed to print as the last thing as I am going to guess you're assuming.
It should be able to print something. A few ideas for testing:
comment the println statements in your runnable - maybe it gets printed but you don't see it because there's too much output on the console
add a System.println(threads.size()) before the do statement to see how many threads have been added (should print 500).
add a Thread.sleep(100) before the do statement. Maybe the first thread gets alive after the do-while block has finished...
I'm having a-bit of trouble with threads in java. Basically Im creating an array of threads and starting them. the point of the program is to simulate a race, total the time for each competitor ( i.e. each thread ) and pick the winner.
The competitor moves one space, waits ( i.e. thread sleeps for a random period of time between 5 and 6 seconds ) and then continues. The threads don't complete in the order that they started as expected.
Now for the problem. I can get the total time it takes for a thread to complete; what I want is to store all the times from the threads into a single array and be able to calculate the fastest time.
To do this should I place the array in the main.class file? Would I be right in assuming so because if it was placed in the Thread class it wouldn't work. Or should I create a third class?
I'm alittle confused :/
It's fine to declare it in the method where you invoke the threads, with a few notes:
each thread should know its index in the array. Perhaps you should pass this in constructor
then you have three options for filling the array
the array should be final, so that it can be used within anonymous classes
the array can be passed to each thread
the threads should notify a listener when they're done, which in turn will increment an array.
consider using Java 1.5 Executors framework for submitting Runnables, rather than working directly with threads.
EDIT: The solution below assumes you need the times only after all competitors have finished the race.
You can use a structure that looks like below, (inside your main class). Typically you want to add a lot of you own stuff; this is the main outline.
Note that concurrency is not an issue at all here because you get the value from the MyRunnable instance once its thread has finished running.
Note that using a separate thread for each competitor is probably not really necessary with a modified approach, but that would be a different issue.
public static void main(String[] args) {
MyRunnable[] runnables = new MyRunnable[NUM_THREADS];
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
runnables[i] = new MyRunnable();
threads[i] = new Thread(runnables[i]);
}
// start threads
for (Thread thread : threads) {
thread.start();
}
// wait for threads
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
// ignored
}
}
// get the times you calculated for each thread
for (int i = 0; i < NUM_THREADS; i++) {
int timeSpent = runnables[i].getTimeSpent();
// do something with the time spent
}
}
static class MyRunnable implements Runnable {
private int timeSpent;
public MyRunnable(...) {
// initialize
}
public void run() {
// whatever the thread should do
// finally set the time
timeSpent = ...;
}
public int getTimeSpent() {
return timeSpent;
}
}