Thread Magic Tricks: 5 Things You Never Knew You Can Do with Java Threads
Join the DZone community and get the full member experience.
Join For Free
beginner
1. thread names
each thread in your app has a name, a simple java string that’s generated for it when the thread is constructed. the default name values go from "thread-0" to "thread-1", "thread-2" and so on. now comes the more interesting part - threads expose 2 ways you can use to set their names:class suchthread extends thread { public void run() { system.out.println ("hi mom! " + getname()); } } suchthread wow = new suchthread("much-name");
wow.setname(“just another thread name”);
using thread names for debugging
so now that you have access to thread names, following some naming conventions of your own could make your life much much easier when something bad happens. "thread-6" sounds a bit heartless, i’m sure you can think of a better name. couple this with a self assigned transaction id when handling user requests, append it to the thread’s name and you’ve considerably cut down your error solving time.thread.currentthread().setname(context + tid + params + current time, ...);
”queue processing thread, messageid: ab5cad, type: analyzegraph, queue: active_prod, transaction_id: 5678956, start time: 30/12/2014 17:37″ #17 prio=5 os_prio=31 tid=0x00007f9d620c9800 nid=0x6d03 in object.wait() [0x000000013ebcc000]
2. thread priorities
another interesting field threads have is priority. a thread’s priority is a value between 1 (min_priority) to 10 (max_priority), and the default value for your main thread is 5 (norm_priority). each new thread gets the priority of its parent, so if you're not playing with it manually, all your thread priorities are probably set to 5. this is also an often overlooked field of the thread class, and we can access and manipulate it through the methods getpriority() and setpriority() . there’s no way to set this in the thread constructor.
who needs priorities anyhow?
of course not all threads are created equal, some require immediate attention from your cpu while others are just background tasks. priorities are used to signal that to the os thread scheduler. at takipi, where we develop an error tracking and analysis tool, the thread that handles new exceptions for our users gets a max_priority, while threads that handle tasks like reporting new deployments are given a lower priority. one might expect that threads with a higher priority get more time from the thread scheduler working with your jvm. well, that's not always the case.
advanced
3. thread local storage
this one is a bit different than the other creatures we talked about here. threadlocal is a concept that’s implemented off the thread class ( java.lang.threadlocal ), but stores unique data for each thread. as it says on the tin, it provides you with thread local storage, meaning you can create variables that are unique to each thread instance. similar to the way you would have a thread name or priority, you can create custom fields that act as if they're members of the thread class. isn’t that cool? but let’s not get too excited , there are some caveats ahead.public static class criticaldata { public int transactionid; public int username; } public static final threadlocal<criticaldata> globaldata = new threadlocal<criticaldata>();
global? it must be evil
not necessarily. a threadlocal variable can keep a transaction id. this can come in handy when you have an uncaught exception bubbling up your code. a good practice is to have an uncaughtexceptionhandler in place, which we also get with the thread class but have to implement ourselves. once we reach that stage, there aren’t many hints as to what actually got us there. we’re left with the thread object and can’t access any of the variables that go us there as the stack frames shut down. in our uncaughtexceptionhandler, as the thread takes its last breaths, threadlocal is pretty much one of the only things we have left.system.err.println("transaction id " + globaldata.get().transactionid);
4. user threads and daemon threads
back to our thread class. each thread in our app receives either a user or a daemon status. in other words, a foreground or a background thread. by default, the main thread is a user thread and each new thread gets the status of the thread that created it. so if you set a thread as daemon, all the threads it creates will be marked as daemon as well. when the only threads left running in your app are of daemon status, the process closes. to play around, check and change a threads status we have the boolean .setdaemon(true) and .isdaemon() methods.when would you set a daemon thread?
you should change a thread’s status to daemon when it’s not critical for it to end so the process could close. it takes off the hassle of closing the thread properly, stopping everything at once and let’s it end quickly. on the other hand, when there’s a thread that runs an operation that must end properly or else bad things will happen, make sure it's set as a user thread. a critical transaction could be, for example, a database entry or completing an update that can't be interrupted.expert
5. java processor affinity
this part takes us closer to the hardware, where the code meets the metal. processor affinity allows you to bind threads or processes to specific cpu cores. this means that whenever that specific thread executes, it would run exclusively on one certain core. normally what would happen is that the os thread scheduler would take on this role according to its own logic, possibly taking the thread priorities we mentioned earlier into account.testing processor affinity
java doesn’t have native support for processor affinity but that’s not the end of the story of course. on linux, we can set a process affinity using the taskset command. say we have a java process running and we want to pin it to a specific cpu:affinitylock al = affinitylock.acquirelock();
conclusion
we’ve seen 5 ways to look at threads: thread names, thread local storage, priorities, daemon threads and affinity. hope this helped shed a new light on the things you deal with on a daily basis, and would be glad to hear your comments! what other thread handling methods could fit in?Opinions expressed by DZone contributors are their own.
Comments