I'm working with Threads in Java using Netbeans 6.9.1 on Ubuntu 10.04 x86_64. I have a problem using the method yield() because when I invoke this method the current thread keeps running instead of stopping and let other threads execution.
The code below it's an easy example to run 2 threads using yield. Instead of run the first thread, print one line and then stop the thread, the program finishes the thread 1 and then runs thread2, as the method yield is not called. I have tested this code on Windows and it works perfectly! so I wonder if there is any issue to use this method on Ubuntu or on 64bits platforms.
Any idea? Thanks in advance.
//ThreadTest.java
public class ThreadTest extends Thread{
public ThreadTest (String name){
super(name);
}
public void run(){
for (int i=0;i<5;i++){
System.out.println(getName()+" - "+i);
yield();
}
System.out.println(" END "+getName());
}
}
//Main.java
public class Main {
public static void main(String[] args) {
ThreadTest t1 =new ThreadTest("Thread1");
ThreadTest t2 =new ThreadTest("Thread2");
t1.start();
t2.start();
}
}
yield is simply a request for another thread to be scheduled. There is nothing that prevents the JVM or underlying OS from scheduling the same thread again.
The javadoc for yield() method in sun JDK 6 and JDK 7 is different, you may need to check the javadoc for the version of JVM you are using.
Related
I am debugging a Java Application in NetBeans IDE 8.0.2.
When a Thread.start() method is called I am not able to reach the run() method of that thread (though I put the breakpoints in that method).
However, sometimes it is hitting the method but sometimes not.
How can I reach the run() method while debugging?
public class JavaApplication7 {
public static void main(String[] args) {
Mailthread1 mt1 = new Mailthread1();
Thread pt = new Thread(mt1);
pt.setName("Mailthread");
pt.start();
}
}
And the Thread class is :
class Mailthread1 implements Runnable {
public void run() {
System.out.println("Cant hit this line");
}
}
in the JDWP, there are 3 types of breakpoint: class, method and line.
If your IDE fails to intercept the line breakpoint in the println(), then you can try a method breakpoint on the run() reclaration.
If that fails, there is something out of sync between the byte code and the source. You can try adding lines, breakpointing another line above and below.
Other than that, change IDE and/or change JVM. This should work.
You don't have a t.join() nor a sleep in the main branch of your code so the new thread starts in theory but your main method also keeps running and exits. The application terminates before it even has a chance to do something in your other thread and the breakpoint is not reachable.
I noticed that I could compile multiple java programs/classes from the command line at the same time.
Here's how I did it (they have to be in the same folder/location):
open command prompt
locate file
type "javac filename1.java filename2.java filename3.java..."
Is it possible to run them at the same time too?
I've tried to do this multiple times, but it just doesn't seem to work. Either I get an error message, or the program fails to run.
Any Suggestions?
Yes it is possible to run multiple java programs simultaneously. One way is to create a java program like so
class Main{
public static void main(String[]args){
new Thread(){
#Override
public void run(){
NameOfFirstJavaAppClass.main(fill,in,the,args);
}
}.start();
new Thread(){
#Override
public void run(){
NameOfSecondJavaAppClass.main(fill,in,the,args);
}
}.start();
}
}
I'm using JNI to invoke a static java method which in turn creates a Swing JFrame and displays it. The code is fairly simple, and the Java-code is working standalone (i.e. java StartAWT does what it should) whereas when called from C using JNI the process hangs.
I'm using the JDK 1.7.0_09 on Mac OS X 10.8 Mountain Lion.
This is the C code I'm using to invoke the static method:
JavaVM* jvm;
JNIEnv* env = create_vm(&jvm);
jclass class = (*env)->FindClass(env, "StartAWT");
jmethodID method = (*env)->GetStaticMethodID(env, class, "run", "()V");
(*env)->CallStaticVoidMethod(env, class, method);
(*jvm)->DestroyJavaVM(jvm);
The StartAWT class looks like this:
public class StartAWT {
public static class Starter implements Runnable {
public void run() {
System.out.println("Runnning on AWT Queue.");
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("That's a frame!");
JLabel label = new JLabel("A Label");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
}
public static class GUI implements Runnable {
public void run() {
try {
System.out.println("Going to put something on the AWT queue.");
SwingUtilities.invokeAndWait(new Starter());
} catch (Exception exc) {
throw new RuntimeException(exc);
}
}
}
public static void run() {
Thread gui = new Thread(new GUI());
gui.start();
}
}
When I start the application, I do see Going to put something on the AWT queue but not Running on AWT Queue.
I believe that the Virtual Machine inside my C Process does not have an AWT event queue but I don't know how to set it up for having one either (nor am I sure that this is the reason).
What is to be done in order to show an AWT based GUI using JNI ?
--
EDIT: I've inserted loops to see which threads are alive and which are not (can be seen in this gist). In this version I do the invocation of SwingUtilities.invokeAndWait in another thread. The result: The main thread is alive (C). The first thread dispatched by Java (not the main thread) is alive; the thread doing the Call invokeAndWait is blocked (I don't think that invokeAndWait did even return), the function which should be run on the EventQueue is not even entered.
I've also tried invoking SwingUtilities.invokeAndWait directly, which will give the following message:
2013-02-02 13:50:23.629 swing[1883:707] Cocoa AWT: Apple AWT Java VM was loaded on first thread -- can't start AWT. (
0 liblwawt.dylib 0x0000000117e87ad0 JNI_OnLoad + 468
1 libjava.dylib 0x00000001026076f1 Java_java_lang_ClassLoader_00024NativeLibrary_load + 207
2 ??? 0x000000010265af90 0x0 + 4335185808
)
This is also what I've read in other questions here on StackOverflow, such as the one suggested in the comments below. However, I could not find a solution to the original problem. Maybe it is worth noting that after the above message came up the main thread is still alive, i.e. neither did the process deadlock nor crash.
--
EDIT: I tested the code on Linux where it is working as expected. So I believe this is a Mac OS X issue with Cocoa AWT, but I don't know how to circumvent it.
--
EDIT: I also tried moving the entire invocation of the JVM onto a new native thread. This works on Mac OS X 10.6 with Apples Java 32-bit (1.6.0_37), but results in the same deadlock as described above. On Mac OS X 10.8 this is worse, the application crases with the only message "Trace/BPT trap: 5" (which seems to be related to loading dynamic libraries).
I also tried bundling the binary as described in this Q&A, but the launch fails with the message lsopenurlswithrole() failed with the message -10810, which is an unknown error, according to Apples Launch Services Reference. The latter also happens without attempting to use AWT (the mere JVM invocation fails).
Finally I found a solution.
The problem is not on which thread the Virtual Machine is being created, the problem is on which thread the AWT Event Queue is being initialized. In other words: The first time that an AWT class is loaded, it may not be loaded on the main thread. Thus step 1: Load (for example) java.awt.Component on another thread.
But now the EventQueue will block, as it delegates work to the Cocoa Main Event Queue which is not running - sure enough, since it will only run on the main thread and the main thread is my application. Thus the main run loop needs to be started on the main thread:
void
runCocoaMain()
{
void* clazz = objc_getClass("NSApplication");
void* app = objc_msgSend(clazz, sel_registerName("sharedApplication"));
objc_msgSend(app, sel_registerName("run"));
}
I had to link my application with the Cocoa framework and include <objc/objc-runtime.h>. The main thread is blocked after the call to runCocoaMain (since the event loop is running there), so one needs to resort to another thread for the application itself.
After running the EventQueue using the above snippet the loading of the AWT class on the other thread will succeed and you can proceed there.
I resolved similar problem by instructions of OSX: JavaVM, AWT/Swing and possibly a deadlock , that is to start CFRunLoopRun() after start JVM in another thread.
In Java, suppose if I start 1000 threads with a loop as below, is there any way I can monitor the number of threads actually running and the CPU resources that the threads consume with task manager?
for(int j=0; j<=1000; j++)
{
MyThread mt = new MyThread ();
mt.start ();
}
You can use VisualVM or JConsole or any other monitoring tool
If you mean the Windows task manager then yes, you can customize the columns shown in the process tab:
Menu View > Select Columns > Threads
EDIT
A quick test shows that creating an additional thread does increment that counter by one - and when that thread terminates, the counter decrements.
But it starts with more than one thread, because it probably includes the various JVM threads too (it starts with 19 threads). Note that jconsole shows 10 threads on a mono-thread program too.
If you use visual VM, you can see the split between daemon and non daemon threads (all JVM threads are daemon).
Test code:
public static void main(String[] args) throws InterruptedException {
Thread.sleep(3000);
Runnable r = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {}
}
};
for (int i = 0; i < 5; i++) {
new Thread(r).start();
Thread.sleep(1000);
}
Thread.sleep(10000);
}
In code you can use Thread.activeCount() method
I think Visual VM is a better tool for this purpose. You'll get threads and a lot more information if you download and install all the plugins.
You can use managed bean for this perpers (MXBean). For example ThreadMXBean.
To get MXBean just call
ManagementFactory.getThreadMXBean()
The methods getThreadCount() and getCurrentThreadCpuTime() will help you.
If you just want to check the thread count in Windows 10
Task manager -> Details -> (right click) Select columns -> (check) Threads
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Printing message on Console without using main() method
Can someone suggest how can a JAVA program run without writing a main method..
For eg:
System.out.println("Main not required to print this");
How can the above line be printed on console without using the public static void main(String arg[]) in the class.
Up to and including Java 6 it was possible to do this using the Static Initialization Block as was pointed out in the question Printing message on Console without using main() method. For instance using the following code:
public class Foo {
static {
System.out.println("Message");
System.exit(0);
}
}
The System.exit(0) lets the program exit before the JVM is looking for the main method, otherwise the following error will be thrown:
Exception in thread "main" java.lang.NoSuchMethodError: main
In Java 7, however, this does not work anymore, even though it compiles, the following error will appear when you try to execute it:
The program compiled successfully, but main class was not found.
Main class should contain method: public static void main (String[] args).
Here an alternative is to write your own launcher, this way you can define entry points as you want.
In the article JVM Launcher you will find the necessary information to get started:
This article explains how can we create a Java Virtual Machine
Launcher (like java.exe or javaw.exe). It explores how the Java
Virtual Machine launches a Java application. It gives you more ideas
on the JDK or JRE you are using. This launcher is very useful in
Cygwin (Linux emulator) with Java Native Interface. This article
assumes a basic understanding of JNI.
Up until JDK6, you could use a static initializer block to print the message. This way, as soon as your class is loaded the message will be printed. The trick then becomes using another program to load your class.
public class Hello {
static {
System.out.println("Hello, World!");
}
}
Of course, you can run the program as java Hello and you will see the message; however, the command will also fail with a message stating:
Exception in thread "main" java.lang.NoSuchMethodError: main
[Edit] as noted by others, you can avoid the NoSuchmethodError by simply calling System.exit(0) immediately after printing the message.
As of JDK6 onward, you no longer see the message from the static initializer block; details here.
public class X { static {
System.out.println("Main not required to print this");
System.exit(0);
}}
Run from the cmdline with java X.
Applets from what I remember do not need a main method, though I am not sure they are technically a program.