I am a newbie to Java and wondering whether I can create threads in following way.
Desired Java Code :
Class MyClass {
Myclass(){
Statement1;//Create a thread1 to call a function
Statement2;//Create a thread2 to call a function
Statement3;//Create a thread3 to call a function
}
}
Is it possible to create threads like the above code?
The Java Concurrency tutorial includes a page on defining and starting threads. You might want to read through it along with the other pages in the concurrency tutorial.
Echoing GregInYEG, you should check out the tutorial, but the simple explanation is as follows:
You need to create an object class which either extends Thread or implements Runnable. In this class, create (actually, overload) a void method called "run." Inside this method is where you put the code that you would like this thread to execute once it is forked. It could simply be a call to another function if you wish. Then, when you would like to spawn a thread of this type, create one of these objects and call the "start" (not run!) method of this object. eg newThread.start();
It's important to call "start" and not "run" because a run call will simply call the method just like any other, without forking a new thread.
Still, be sure to read up in further detail and there are many more important aspects of concurrency, especially that of locking shared resources.
Yes, it is possible. You want to put your logic for each statement inside a Runnable implementation, and then pass each constructed Runnable to a new instance of Thread. Check out those 2 classes and it should become fairly obvious what you need to do.
I agree with all written here. The thread can be created in a two ways.
To extend thread class . YouTube Tutorial
To implement Runnable Interface YouTube Tutorial
Example for the first method
public class MyThread extends Thread {
public void run()
{
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Created Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
MyThread myThread = new MyThread();
myThread.start();
Second method to implement runnable interface
public class RunnableThread implements Runnable {
#Override
public void run() {
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Runnable Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
new Thread(new RunnableThread()).start();
So I think you can use both of these methods in you case statements
Related
How do I check if two threads belong to same or different processes programatically? This is the piece of code I have written:
public class MyThread {
public static void main(String[] args) {
TestThread1 obj1 = new TestThread1();
TestThread2 obj2 = new TestThread2();
System.out.println("Current thread:" + Thread.currentThread().getName());
Thread t1 = new Thread(obj1);
t1.start();
Thread t2 = new Thread(obj2);
t2.start();
}
}
class TestThread1 implements Runnable {
#Override
public void run () {
for(int i=0; i<1000 ;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Current thread:" + Thread.currentThread().getName());
}
}
}
class TestThread2 implements Runnable {
#Override
public void run () {
for(int i=0; i<1000 ;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Current thread:" + Thread.currentThread().getName());
}
}
}
Here what I understand is thread t1 being created as part of process TestThread1 and thread t2 being created as part of TestThread2 process. But how do i check this programatically?
You mixed the concept of threads and processes.
thread t1 being created as part of process TestThread1 and thread t2
being created as part of TestThread2
Your TestThread1 and TestThread2 are just runnables, that hold information what action should be done by thread. Your t1 and t2 are actual threads, they run in the same process, because you started them in one application. All threads in the application run in same java process, so you can't have a situation where you have two threads referecens and they belong to different processes.
If you start another java application, it will run in a different process, but you won't be able to compare two threads from different processes in a single context.
There is something wrong with your understanding or your use of terminology.
Here what I understand is thread t1 being created as part of process TestThread1 and thread t2 being created as part of TestThread2 process.
First of all, some terminology:
TestThread1 and TestThread2 are classes not processes.
The values in obj1 and obj2 are not processes either. They are instances of the TestThread1 and TestThread2 classes respectively.
If I interpret your question correctly, you are actually asking if there is a way to find out if t1 and t2 share a single Runnable instance. Unfortunately, there isn't a way to do that in pure Java. A Thread object's Runnable is a private field and there is no public getter for retrieving it1.
On the other hand, if you are really asking about processes ...
When you run the application, there will be only one process, and both threads will belong to it.
1 - It is possible to use nasty reflection to retrieve the private field's value, but it is a bad idea. You should look for a way to do whatever you are trying to do that doesn't entail this test ...
Maybe there is an easier way, but you could call getStackTrace() on a thread and then inspect it (search for the run method's frame). However, this will work only for live threads.
PS You use wrong terminology here, what you refer to is not a process, it is just a class that defines the run method which is executed by the thread.
Im not sure exactly what the problem is but for some reason I cant get threads from two classes to run at the same time. I can get multiple threads from one class to run at the same time, but when I try to start another class nothing happens.
public professor(){
prof = new Thread();
prof.start();
System.out.println("Prof has started1");
}
public void run(){
try{
System.out.println("Prof has started2");
prof.sleep(600);
//do more stuff
}
catch(Exception e){
System.out.println("Prof error");
}
This is how I started my second class, the first one is started in the exact same way and runs fine. With this class however "Prof has started1" gets displayed, but the second one never does.
Am I missing something?
I think this is the reason
prof = new Thread();
prof.start();
This code will never call your own run() method, if your class implements the runnable interface, you should do this
prof = new Thread(this)
prof.start()`
You don't provide the full delcartion the Professor class so the exact solution may vary but the main point that I see is this: you create an instance of the Thread class and then invoke .start():
prof = new Thread();
prof.start()
Alas, the Thread class by itself does not do any thing when you call .start() on it. you need to tell it what is the action that you want it to carry out once it has been start()-ed. There are several ways to do so, but I will go with this:
public professor() {
prof = new Thread(new Runnable() {
public void run() {
try {
System.out.println("Prof has started2");
Thread.currentThread().sleep(600);
//do more stuff
}
catch(Exception e){
System.out.println("Prof error");
}
}
});
prof.start();
System.out.println("Prof has started1");
}
public void run() {
}
That is: create an instance of Runnable in which you override the run() such that it does whatever you want it to do. Then pass this instance of Runnable to the constructor of the Thread object you're creating. When you subsequently invoke .start() the run() method of that Runnable will get executed.
I have a class "TestRunnable" which overrides run method by implementing Runnable.
Running overridden run method, as follow :
TestRunnable nr = new TestRunnable();
Thread t = new Thread(nr);
t.setName("Fred");
t.start();
What if i directly call t.run();
What happen if we don't call t.start(); ?
The run method is just another method. If you call it directly, then it will execute not in another thread, but in the current thread.
Here's my test TestRunnable:
class TestRunnable implements Runnable
{
public void run()
{
System.out.println("TestRunnable in " + Thread.currentThread().getName());
}
}
Output if only start is called:
TestRunnable in Fred
Output if only run is called:
TestRunnable in main
If start isn't called, then the Thread created will never run. The main thread will finish and the Thread will be garbage collected.
Output if neither is called: (nothing)
If you call start method then a separate thread will be allocated to execute the run method, means you achieve multi threading . But when you call run method directly then it becomes a normal method and main method itself will execute the run method , means no multi threading.
If run() method is called directly instead of start() method in Java code, run() method will be treated as a normal overridden method of the thread class (or runnable interface). This run method will be executed within the context of the current thread, not in a new thread.
Example
Let’s create a class and spawn two threads and cause some delay in the execution if they are real threads then there will be context switching – while one thread is not executing another thread will execute. When the start method is not called no new threads are created thus there won’t be any context switching and the execution will be sequential.
public class MyThreadClass extends Thread{
#Override
public void run(){
System.out.println("In run method " + Thread.currentThread().getName());
for(int i = 0; i < 5 ; i++){
System.out.println("i - " + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThreadClass mc1 = new MyThreadClass(“MyThread1”);
MyThreadClass mc2 = new MyThreadClass();
mc1.run();
mc2.run();
}
}
Is it possible to tell the JVM (or some appropriate object) to execute a given block of code every time a new thread is created?
No, not using standard Java.
Have a look at aspect oriented programming, such as AspectJ. You should probably be able to create a point-cut for the Thread constructor.
Not every time a new thread is created. However, if you use a ThreadPoolExecutor to create new threads, you can specify a ThreadFactory, which can run a specific block of code every time a thread is created by that factory. A simple example (where the block of code to run prints the name of the thread) would look like:
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
System.out.println("New thread created: " + t); //Your block of code
return t;
}
});
Runnable r = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
for (int i = 0; i < 5; i++) {
executor.submit(r);
}
executor.shutdown();
}
It depends on your use case, but you could also do Java byte code instrumentation. This is, however, normally used for measuring, error tracing, profiling, etc. since it has noticeable performance impacts.
This can be done with ASM, they have a tutorial to get started or take a look at the guide Add Logging at Class Load Time with Java Instrumentation, they explain how to modify the Java code in a way, that code is added each time a method is entered and exited.
In your case you would do this only for special methods, either the Thread() constructor or the invocation of Thread.start().
In my application, I have one text field and a button. After focus lost from text field first swing worker (lets assume it as sw1) is called. Which opens a pop-up to populate value to put in text field. Second swing worker (lets assume it as sw2) is called after user clicks a button.
Now the issue is that if I write something in text field and then click on button, sw1 is started first to calculate the value to put in text field and at the same time sw2 is also started. And sw2 finishes first and then sw1 populates result. What I want is sw2 should wait for sw1 to finish. Once sw1 finishes its task, it will notify sw2.
I referred so many references over the internet and stackoverflow. This is the one which almost matches to my requirement.
I tried to create a static final object inside class which starts sw1:
public final static Object lockObject = new Object();
Then inside done() method of sw1, I have written code like:
synchronized(lockObject) {
sw1.notifyAll();
}
Inside doInBackground() method, of the second class, on first line, I have written code like:
synchronized(FirstClass.lockObject) {
try {
sw2.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
But I am getting java.lang.IllegalMonitorStateException, at java.lang.Object.notifyAll(Native Method). Can anybody tell me what is the issue and how to make it work the way I want.
Update: As per Ernest's solution I modified my code and it looks like now:
FirstClass.java
public final static Object lockObject = new Object();
public static boolean flag = false;
someMethod() {
synchronized(lockObject){
sw1.doInbackground() {
......
}
sw1.done() {
.....
flag = true;
lockObject.notifyAll();
}
}
}
SecondClass.java
anotherMethod() {
sw2.doInbackground() {
try {
while (!FirstClass.flag) {
FirstClass.lockObject.wait();
}
FirstClass.flag = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
......
}
}
But still I am getting java.lang.IllegalMonitorStateException on lockObject.notifyAll() line. Can you please tell if I am doing it correctly?
Thanks.
Your code should look something like this.
FirstClass.java
public final static Object lockObject = new Object();
public static boolean flag = false;
someMethod() {
sw1.doInbackground() {
......
}
sw1.done() {
.....
}
synchronized(lockObject){
flag = true;
lockObject.notifyAll();
}
}
SecondClass.java
anotherMethod() {
sw2.doInbackground() {
try {
synchronized(lockObject){
while (!FirstClass.flag) {
FirstClass.lockObject.wait();
}
FirstClass.flag = false;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
......
}
}
But. Synchronizing on a global static object will get you in trouble if you have more than one instance of FirstClass.java and SecondClass.java. You should really find a way to pass the object instances around.
If I understood correctly your use case, can't you simply disable the button for sw2 when the user starts editing the field, and re-enable it when the first worker finishes? It would be much more clear for the user as well.
You need not to reinvent such a simple synchronization facility. For example, you can use CountDownLatch. Sw1 does countdown and sw2 - await.
You can only call wait() and notify() on an object whose monitor you hold. In each of your code snippets, you're locking one object, but calling these methods on another. It just doesn't work that way. I'm afraid I can't quite make out what you're trying to do, so it's hard to give you specific corrections, but basically, these blocks need to look something like
synchronized(sw2) {
try {
sw2.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Let's say there are two threads, T1 and T2, and there is some object O1. Then if code running on thread T1 wants to wait until code in thread T2 says it's OK to continue, it must synchronize on object O1 and then call O1.wait(). When code running on T2 wants to send that message to T1, it must synchronize on O1 and call O1.notify() (or O1.notifyAll().) It doesn't matter what object you use for O1, but the code in both threads must agree to use the same object.