Would it be possible to implement a custom Thread class in Java (using JNI) in a safe / correct way?
Suppose I write my own NewThread class, with a native start() method, which forks the execution, calls run() in the forked thread and returns...
Is that possible? Would the JVM complain? Is it "legal" according to the specs? Would this break anything, like, in the memory-model? Does it depend on the particular JVM?
Your questions is answered in the Java Native Interface
Programmer's Guide and Specification, section 8.1.5.
The important issue is that the VM has to use the same thread model as you are in your native code. Some of the first Java VMs used so called "green threads" on some operating systems (Linux) to emulate thread context switching, since the operating system itself didn't offer native threading support. These "green threads" would not be able to interact with native threads, if you would use one of these old VMs on a newer operating system version with native thread support.
Since Sun's JRE 1.3, I think all "normal" VMs are using native threads directly, which means that you can use native threads yourself in JNI code and expect everything to work as you expect.
It is possible. In the past I was using a C++ lib that read messages for the socket. After the initialization through JNI the library started a couple of pthreads that read data from the socket and did calls in the Java realm through JNI. The said pthreads where venturing pretty deep into the Java code. The only problems we had were memory issue on the JNI seam. After reading the JNI docs and some debugging the issues where solved. So, no problems with memory model.
Don't know if JVM will trigger JIT based on executions incoming from JNI, so could be a performance hit there.
Doable, tricky in places. If you can do with Java Threads, avoid this. I know I would.
Related
For example, I use Java to write a multi-threaded program with 5 threads. When I execute it, does the operating system (e.g. Windows 7) know that or it is just one task?
That depends on the JVM implementation.
However, in Linux platform , USUALLY there is one-one mapping between java thread and native thread.
Alternatively, the JVM could chose to implement using many-one mapping ,that is many java thread are running on one single native thread. This is called Green Thread.
Modern JVMs tend to use operating system threads, but it isn't specified, and the JVM is free to do otherwise.
It is obvious that OS scheduling/ threading algorithms have their impact on Java threads but
can we safely say that Threads are OS/machine dependant?
If this is the case then doesn't it make Java platform dependant?
Yes, the details of the scheduling of threads in Java depends on the JVM implementation and (usually) on the OS implementation as well.
But the specifics of that scheduling is also not specified in the Java SE specification, only a selected few ground rules are specified.
This means that as long as the OS specific scheduling is conforming to those ground rules, it is also conforming to the JVM spec.
If your code depends on scheduling specifics that are not specified in the JVM spec, then it depends on implementation details and can not be expected to work everywhere.
That's pretty much the same situation as file I/O: if you hard-code paths and use a fixed directory separator, then you're working outside the spec and can not expect your code to work cross-platform.
Edit: The JVM implementation itself (i.e. the JRE) is platform dependent, of course. It provides the layer that allows pure Java programs to not care about the platform specifics. To achieve this, the JRE has to be paltform specific.
... Java will usually use native threads, but on some operating
systems it uses so called "green threads", which the JVM handles
itself and is executed by a single native thread.
You shouldn't have to worry about this. It is all handled by the JVM,
and is invisible to the programmer. The only real difference I can
think of is that on an implementation that uses green threads, there
will be no performance gain from multi-threaded divide-and-conquer
algorithms. However, the same lack of performance gain is true for
implementations that use native threads, but run on a machine with a
single core.
Excerpt from JVM & Java Threads Scheduling
Even on the same platform, if you write unsafe multi-thread code, behavior can depend on the full configuration details, the rest of the machine load, and a lot of luck, as well as hardware and OS. An unsafe program can work apparently correctly one day, and fail the next on the same hardware with more-or-less the same workload.
If you write safe multi-thread code, code that depends only on what is promised in the Java Language Specification and the library APIs, the choice of platform can, of course, affect performance, but not whether it works functionally.
I have chat server application which we are going to deploy on 3 servers. chat application used lot of multithreading.
Basically i have to decide which os i should for those 3 servers. so i want to know how linux and windows handles java threads distinctively. what is the difference? who creates operating system threads? what memory are they assigning ?
If in future scope scalability and clustering which option is better?
If in future scope scalability and clustering which option is better?
Scalability and clustering are most likely hampered by the internal design of your code not by the JVM nor by the underlying OS. And without taking a very deep look into the code every statement about this is just hot noise but not a profound statement.
But the nice thing about Java is: It will run on both platform without changing your code. So the best you can do is: Benchmark both OSes on the same hardware (but do not use any kind of virtualization!) and use the best one for your purpose.
how linux and windows handles java threads distinctively.
The beauty of Java is that you don't really care. They just work. But if you are really curious, modern JVMs delegate thread handling to the operating system. So it is more of an OS question rather than Java.
what is the difference?
See above. Java has little to do here. It is about how threading is implemented in the host OS.
who creates operating system threads?
JVM asks OS to create them and provides a thin wrapper between Java Thread object and native threads.
what memory are they assigning ?
Each thread gets its own stack (seee -Xss JVM option). Also all threads share the same heap space.
What is the difference between threads in java and native threads?
Java threads can be implemented in any way that conforms to the specification. The specification doesn't require a specific implementation.
Effectively all modern desktop and/or server JVMs implement Java threads as native threads. That means that there is exactly 1 native thread for each Java thread and that the operating system does all the scheduling, just as it does for a C program, for example.
Some old JVMs and possibly some JVMs for devices with limited resources might implement threads in a way where the number of native threads used is smaller than the number of Java threads running (or possibly 1). Those implementations are said to implement so called "green threads". In this case the JVM itself is responsible for task switching and scheduling, as opposed to delegating that task to the operating system.
It depends on the implementation of the JVM, of course, but I think they are the same. It is, a Thread in Java is implemented via a native thread. You can expect/do with Java threads all kind of things you can with native threads.
Java threads and Native threads are completely different. Native thread is part of underlying platform (the OS).
Java threads are one of the feature of Java Language for supporting concurrency. Java specification controls API and functioning of Java threads. Ultimately Java threads will be mapped to native threads during execution of the java program.
Also java threads needn't get one to one mapped with native threads.
Java Threads (Thread class and Runnable interface) are a much higher-level API than native threads in memory-shared applications. I recommended this book "Java Threads" by Oaks and Wong http://shop.oreilly.com/product/9780596007829.do. It's common practice to implement the Runnable interface, but it depends on your code scope.
Does anybody know of a way to lock down individual threads within a Java process to specific CPU cores (on Linux)? I've done this in C, but can't find how to do this in Java. My instincts are that this will require a JNI call, but I was hoping someone here might have some insight or might have done it before.
Thanks!
You can't do this in pure java. But if you really need it -- you can use JNI to call native code which do the job. This is the place to start with:
http://ovatman.blogspot.com/2010/02/using-java-jni-to-set-thread-affinity.html
http://blog.toadhead.net/index.php/2011/01/22/cputhread-affinity-in-java/
UPD: After some thinking, I've decided to create my own class for this: ThreadAffinity.java It's JNA-based, and very simple -- so, if you want to use it in production, may be you should spent some time making it more stable, but for benchmarking and testing it works well as is.
UPD 2: There is another library for working with thread affinity in java. It uses same method as previously noted, but has another interface
I know it's been a while, but if anyone comes across this thread, here's how I solved this problem. I wrote a script that would do the following:
"jstack -l "
Take the results, find the "nid"'s of the threads I want to manually lock down to cores.
Taskset those threads.
You might want to take a look at https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/test/java/com/higherfrequencytrading/affinity/AffinityLockBindMain.java
IMO, this will not be possible unless you use native calls. JVM is supposed to be platform independent, any system calls done to achieve this will not result in a portable code.
It's not possible (at least with plain Java).
You can use thread pools to limit the amount of threads (and therefore cores) used for different types of work, but there is no way to specify a core to use.
There is even the (small) possibility that your Java runtime doesn't support native threading for your OS or hardware. In this case, green threads are used and only one core will be used for the whole JVM.