I make two threads: one for fill an array and the second one print it. It seems like the two thread don't work in same time.
When i run the code its print first thread working then its print the array and second thread working how i can know if they working on same time or not?
here is my code:
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
firstthread f=new firstthread();
secondthread s=new secondthread();
s.start();
f.start();
}
}
and the class the contain both fill and print method:
public class Array {
private static int [] ar=new int[500];
public static void fillarray()
{
for (int i = 0; i < ar.length; i++)
ar[i]=i;
}
public static void printarray()
{
for (int i = 0; i < ar.length; i++)
System.out.print(ar[i]+" ");
}
}
the first thread class:
public class firstthread extends Thread{
public void run() {
Array.fillarray();
System.out.print("first thread working ");
}
}
the second thread class:
public class secondthread extends Thread{
public void run() {
Array.printarray();
System.out.println("second array working");
}
}
The fillarray and printarray methods are running too fast so you aren't getting threading.
Add Thread.sleep(10) to each loop. That way the code will run much slower and the threads will intersperse. They will probably alternate with this approach.
Then change in to sleep a random # of seconds and you'll see different behavior.
You want an implementation of producer-consumer problem bro... Frankly speaking, without having a lock on the Object's monitor, you dont have control over anything. You dont have control over how much time a thread executes (Timeslice provided to it). If the time slice is too long, you will feel that one thread executes after another because your processor is so fast, your first thread will get ample time to finish its work . If you want to know how threads work exactly, use wait() and notify() and synchronized methods to change it into a producer-consumer problem.
Jeanne is also right, you can put sleep() , there's a 90 percent chance that it might work.
You could increase the number of elements being filled/printed.
There's a 70% chance of you reading more than what you wrote(filled in the array) if you dont use syncronized/wait/notify.
Starting a thread takes some time to the JVM. The first thread executes its run() method faster than the other thread is started. That's why you see that behavior.
Question isn't clear. Do you mean how can you tell if they are working on the same array? If that is the case the answer is Yes. the array is static meaning there would be only one of its kind which would belong to the class array. So there wont be multiple instances of it being worked on by the different threads.
As stated above, the threads run very fast. So even though they are accessing the same object, one thread would finish its job before the second even begins
Related
I am currently working on understanding the Java concept of multithreading. I went through a tutorial which uses the Tortoise and the Hare example to explain the concept of multithreading, and to a large extent I understood the syntax and the logic of the video tutorial. At the end of the video tutorial, the Youtuber gave an assignment that involves applying Multithreading to an olympic race track.
Using my knowledege from the example, I was able to create 10 threads (representing the athletes) that run within a loop, that executes 100 times (representing 100 meters).
My challenge is that when the Thread scheduler makes an Athlete to get to 100 meters before the other 9 athletes, the remaining 9 threads always do not complete their race. This is not usually the case in a standard race track. The fact that a Thread called Usain Bolts gets to 100 first, does not mean Yohan Blake should stop running if he is at 90m at that time.
I am also interested in getting the distance (note that they are all using the same variable) for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
What I have done (that did not work):
1) I have tried to use an if else construct (containing nine "else"
statement) to assign the distance of each executing thread to a new integer variable. (using the Thread.currentThread().getName() property and the name of each thread) but that did not work well for me. This was an attempt to give positions to the athletes alone using their distance but does nothing about the 9 athletes not finishing the race.
2) I have also tried to use an ArrayList to populate the distance at runtime but for some strange reasons this still overwrites the distance each time it wants to add another distance.
Below are my codes:
package olympics100meters;
import java.util.ArrayList;
public class HundredMetersTrackRules implements Runnable {
public static String winner;
public void race() {
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread ().getName ()+" is "+distance+" meters.");
boolean isRaceWon=this.isRaceWon(distance);
if (isRaceWon) {
ArrayList<Integer> numbers = new ArrayList();
numbers.add(distance);
System.out.println("testing..."+numbers);
break;
}
}
}
private boolean isRaceWon(int totalDistanceCovered) {
boolean isRaceWon=false;
if ((HundredMetersTrackRules.winner==null)&& (totalDistanceCovered==50)) {
String winnerName=Thread.currentThread().getName();
HundredMetersTrackRules.winner=winnerName;
System.out.println("The winner is "+HundredMetersTrackRules.winner);
isRaceWon=true;
}
else if (HundredMetersTrackRules.winner==null) {
isRaceWon=false;
}
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
return isRaceWon;
}
public void run() {
this.race();
}
}
This is my main method (I reduced it to 5 Athletes till I sort out the issues):
public class Olympics100Meters {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules();
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
}
}
My challenge is that ... the remaining 9 threads always do not complete their race.
This is caused by isRaceWon() method implementation. You check for it at each meter at each runner. As soon as the first runner achieves 100 meters, the break is called on next step of each runner loop (the race is won for every loop
btw, it makes sense to use volatile statuc String for winner's name, to avoid java's memory model ambiguities.
I am also interested in getting the distance ... for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
If the final aim is to get the position, create a class field public List<String> finishingOrder = new ArrayList<String> and a method finish
private synchronized finish() {
finishingOrder.add(Thread.currentThread().getName())
}
and call it after the "run" loop
do not forget to call join() for all runner threads in your main. After that, the finishingOrder will contain names in order of finishing.
The code snippet below is causing isRaceWon to return true for every instance of HundredMetersTrackRules as soon as the shared winner field is set to non-null (i.e. someone wins.):
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
This in turn causes the loop in race() to break for every instance of your Runnable. The run() method exits, terminating the thread.
The issue is just a logic error and not really specific to threading. But, as other posters have mentioned, there's some threading best-practices you can also adopt in this code, such as using volatile for fields shared by threads.
Actually For Race you need to start all the Threads at once then only its Race.
CountDownLatch is better one to Implement or write Race Program.
Many other way also we can write Race program without using the CountDownLatch.
If we need to implement using base / low level then we can use volatile boolean Flag and counter variable in synchronized blocks or using wait() and notifyAll() logic, etc.,
Introduced some time delay in your program inside the for loop. Then only you can feel the Experience. Why because you are not starting all the threads at once.
Hope you are Practicing Initial / base Level so I made few changes only for better understanding and Addressed all your queries.
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
class HundredMetersTrackRules implements Runnable {
public static Main main;
HundredMetersTrackRules(Main main){
this.main=main;
}
public static String winner;
public void race() {
try{
System.out.println(Thread.currentThread().getName()+" Waiting for others...");
while(!Main.start){
Thread.sleep(3);
}
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread().getName()+" is "+distance+" meters.");
Thread.sleep(1000);
}
synchronized(main){
Main.finish--;
}
Main.places.add(Thread.currentThread().getName());
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
public void run() {
this.race();
}
}
public class Main
{
public static volatile boolean start = false;
public static int finish = 5;
final static List<String> places =
Collections.synchronizedList(new ArrayList<String>());
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules(new Main());
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
Main.start=true;
while(Main.finish!=0){
try{
Thread.sleep(100);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
System.out.println("The winner is "+places.get(0));
System.out.println("All Places :"+places);
}
}
Is there a way to create multiple threads that run simultaneously with a for loop? Consider this example:
for(int i = 1; i<=36; i++) {
if(new Random().nextInt(2)==0){
ActionThread nr = new ActionThread();
}
}
I don't want the threads to be killed after completion of the if statement. The end of each thread is randomly determined in the ActionThread class itself. Also, how do I name the threads automatically? For example, instead of nr, the first thread should be named nr1, the second nr2, the third nr3, and so on.
I'm assuming that ActionThread is some custom class that you have created that extends Thread.
I don't want the threads to be killed after completion of the if statement.
They won't be. However, it doesn't look like you have started them yet. Read the javadocs for Thread. Read the material at the top, then look at the start() and run() methods.
If you don't start a thread ... nothing happens.
Also, if you want some other part of your application to be able to "do things" to the threads once they have been created, you should replace the nr local variable with a data structure that the the rest of the application can get at; e.g. a list or an array.
(It is also possible to find extant threads via the ThreadGroup tree, but it is complicated.)
Also, how do I name the threads automatically?
Call Thread.setName(), or pass the thread name to the (relevant) Thread constructor. For example:
nr.setName("thr" + i);
Or you could even make your ActionThread set its own name in the constructor.
I should also point out that is is generally considered to be a bad idea to create subclasses of Thread. It is better to put your thread logic into a custom Runnable class, then create and pass a Runnable instance as a Thread construct argument. Like this:
public class MyRunnable implements Runnable {
#Override
public void run() {
// thread logic goes here
}
}
Thread th = new Thread(new MyRunnable());
th.start();
If you want to pass parameters to the thread logic, add a constructor to your runnable class with some arguments, and provide them when you instantiate the runnable.
Why do it this way? Because it allows you to easily change your code to use a thread loop or executor or some such.
public static void main(String[] a) {
List<ActionThread> threads = new ArrayList<>();
for (int i = 1; i <= 36; i++) {
if (new Random().nextInt(2) == 0) { // no idea why you have put this
// but seems unecessary
ActionThread thread = new ActionThread();
threads.add(thread);
thread.start();
}
}
}
class ActionThread extends Thread {
#Override
public void run() {
// Write what to do in Thread here
}
}
Once the list of ActionThread is there you have handle to all the Threads that you have created. using threads.get(index). From question its appears that by name you meant handle to Thread instance
For automatic naming, may be use static field (counter) in ActionThread and increment him in the constructor, before generate thread name.
class ActionThread extend Thread {
private static int id = 0;
ActionThread() {
setName(String.format("n%d", ++id);
}
}
Because it always prints out '3'. No synchronization needed? I am testing this simple thing because I am having a trouble in a real multiple thread problem, which isn't good to illustrate the problem, because it's large. This is a simplified version to showcase the situation.
class Test {
public static int count = 0;
class CountThread extends Thread {
public void run()
{
count++;
}
}
public void add(){
CountThread a = new CountThread();
CountThread b = new CountThread();
CountThread c = new CountThread();
a.start();
b.start();
c.start();
try {
a.join();
b.join();
c.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Test test = new Test();
System.out.println("START = " + Test.count);
test.add();
System.out.println("END: Account balance = " + Test.count);
}
Because it always prints out '3'. No synchronization needed?
It is not thread safe and you are just getting lucky. If you run this 1000 times, or on different architectures, you will see different output -- i.e. not 3.
I would suggest using AtomicInteger instead of a static field ++ which is not synchronized.
public static AtomicInteger count = new AtomicInteger();
...
public void run() {
count.incrementAndGet();
}
...
Seems to me like count++ is fast enough to finish until you invoke 'run' for the other class. So basically it runs sequential.
But, if this was a real life example, and two different threads were usingCountThread parallelly, then yes, you would have synchronization problem.
To verify that, you can try to print some test output before count++ and after, then you'll see if b.start() is invoking count++ before a.start() finished. Same for c.start().
Consider using AtomicInteger instead, which is way better than synchronizing when possible -
incrementAndGet
public final int incrementAndGet()
Atomically increments by one the current value.
This code is not thread-safe:
public static int count = 0;
class CountThread extends Thread {
public void run()
{
count++;
}
}
You can run this code a million times on one system and it might pass every time. This does not mean is it is thread-safe.
Consider a system where the value in count is copied to multiple processor caches. They all might be updated independently before something forces one of the caches to be copied back to main RAM. Consider that ++ is not an atomic operation. The order of reading and writing of count may cause data to be lost.
The correct way to implement this code (using Java 5 and above):
public static java.util.concurrent.atomic.AtomicInteger count =
new java.util.concurrent.atomic.AtomicInteger();
class CountThread extends Thread {
public void run()
{
count.incrementAndGet();
}
}
It's not thread safe just because the output is right. Creating a thread causes a lot of overhead on the OS side of things, and after that it's just to be expected that that single line of code will be done within a single timeslice. It's not thread safe by any means, just not enough potential conflicts to actually trigger one.
It is not thread safe.
It just happened to be way to short to have measurable chance to show the issue. Consider counting to much higher number (1000000?) in run to increase chance of 2 operations on multiple threads to overlap.
Also make sure your machine is not single core CPU...
To make the class threadsafe either make count volatile to force memory fences between threads, or use AtomicInteger, or rewrite like this (my preference):
class CountThread extends Thread {
private static final Object lock = new Object();
public void run()
{
synchronized(lock) {
count++;
}
}
}
I am trying to understand the keyword synchronized from the following example
Java Main Method -->
public int methodA(){
Hello h = new Hello();
h.callSomeSynchronizedMethod();
sysout("Main");
return 0;
}
In the Hello Class-->
public synchronized void callSomeSynchronizedMethod(){
Hi h = new Hi();
h.someMethod();
sysout("Hello");
}
In the Hi class
public void someMethod(){
sysout("Hi");
}
So what would be the list of outputs that i will get;
1.) Is it in the order of Hi, Hello and Main ?
2.) What i understand about the synchronized keyword is that it will only execute 1 method and then execute the other, without multi-threading. Is this correct ?
To really understand what synchronized does you need to run the program twice, once synchronized and once not. Also your program should use multiple threads. So here is an example of such a test.
public class Synchro {
public static void main(String args[]){
new Synchro();
}
public Synchro(){
final Moo moo = new Moo();
Thread t = new Thread(new Runnable(){
public void run(){
moo.aMethod("Second");
}
});
t.start();//calling the method in a thread
moo.aMethod("First");//calling the same method from the same object in the main thread
}
class Moo{
public Moo(){
}
public void aMethod(String name){
//this loop just prints slowly so you can see the execution
for(int i = 1; i <= 100; i++){
System.out.println(String.format("%s : %d", name, i));
try{
Thread.sleep(50);
}catch(InterruptedException e){}
}
}
}
}
Now, if you run the above code, noticing that the method is not synchronized, you will see the printout from the two executions of the method interleaved. That is you will see First 1 then Second 1 then First 2 etc.
Now, add the synchronized keyword to the method making it:
public synchronized void aMethod(String name){ ....
and run the code again. This time, one execution of the method completes before the other begins.
The synchronized keyword is only necessary when multiple threads are accessing the very same object.
You would get "Hi", then "Hello", then "Main", yes. The synchronized modifier has nothing to do with the order the methods are called in; and, other than adding a bit of overhead, it does nothing at all when running the code in a single thread. You could run this same test without synchronized and get the same result.
Now, if you ran a similar test where multiple threads were calling these methods, your results would be less determinate.
Synchronized is meant to allow for the more safe execution of code and management of resources in a multi-threaded environment.
http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Hope this helps.
all these methods will be executed in one thread so the answer for the first question is "yes".
synchronized keyword emans that the method can be executed in only one thread at every moment of time. So if you call it from another thread - it will wait till the execution is finished in the first thread.
In Java there is no automatic multithreading: you must explicitly start a thread and pass it a run method that it will execute. Only in that case will the synchronized keyword start to matter, but its meaning is not quite as you understand it: the methods will execute in whatever thread calls them, but while one is executing, another thread will block before it is able to execute a method guarded by the same lock.
I am fairly naive when it comes to the world of Java Threading and Concurrency. I am currently trying to learn. I made a simple example to try to figure out how concurrency works.
Here is my code:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadedService {
private ExecutorService exec;
/**
* #param delegate
* #param poolSize
*/
public ThreadedService(int poolSize) {
if (poolSize < 1) {
this.exec = Executors.newCachedThreadPool();
} else {
this.exec = Executors.newFixedThreadPool(poolSize);
}
}
public void add(final String str) {
exec.execute(new Runnable() {
public void run() {
System.out.println(str);
}
});
}
public static void main(String args[]) {
ThreadedService t = new ThreadedService(25);
for (int i = 0; i < 100; i++) {
t.add("ADD: " + i);
}
}
}
What do I need to do to make the code print out the numbers 0-99 in sequential order?
Thread pools are usually used for operations which do not need synchronization or are highly parallel.
Printing the numbers 0-99 sequentially is not a concurrent problem and requires threads to be synchronized to avoid printing out of order.
I recommend taking a look at the Java concurrency lesson to get an idea of concurrency in Java.
The idea of threads is not to do things sequentially.
You will need some shared state to coordinate. In the example, adding instance fields to your outer class will work in this example. Remove the parameter from add. Add a lock object and a counter. Grab the lock, increment print the number, increment the number, release the number.
The simplest solution to your problem is to use a ThreadPool size of 1. However, this isn't really the kind of problem one would use threads to solve.
To expand, if you create your executor with:
this.exec = Executors.newSingleThreadExecutor();
then your threads will all be scheduled and executed in the order they were submitted for execution. There are a few scenarios where this is a logical thing to do, but in most cases Threads are the wrong tool to use to solve this problem.
This kind of thing makes sense to do when you need to execute the task in a different thread -- perhaps it takes a long time to execute and you don't want to block a GUI thread -- but you don't need or don't want the submitted tasks to run at the same time.
The problem is by definition not suited to threads. Threads are run independently and there isn't really a way to predict which thread is run first.
If you want to change your code to run sequentially, change add to:
public void add(final String str) {
System.out.println(str);
}
You are not using threads (not your own at least) and everything happens sequentially.