I'd like to make a ThreadPollExecutor that executes tasks with a given priority Process.setThreadPriority(int).
How should I do it? Adding the call to setThreadPriority at the start of each runnable sent to the thread poll? I've also considered using a custom thread factory like this:
private final static class ProcessPriorityThreadFactory implements ThreadFactory {
private final int threadPriority;
public ProcessPriorityThreadFactory(int threadPriority) {
super();
this.threadPriority = threadPriority;
}
#Override
public Thread newThread(Runnable r) {
return new Thread(new PriorityChangeWrapper(r, threadPriority));
}
private final static class PriorityChangeWrapper implements Runnable {
private final Runnable originalRunnable;
private final int threadPriority;
public PriorityChangeWrapper(Runnable originalRunnable, int threadPriority) {
super();
this.originalRunnable = originalRunnable;
this.threadPriority = threadPriority;
}
#Override
public void run() {
Process.setThreadPriority(threadPriority);
originalRunnable.run();
}
}
}
What is the best solution for this problem? Thanks
The custom factory as given in your question is the correct way to do this. The factory pattern is used for just this reason as it gives you total control over all the threads created by the ExecutorService. (For example you can also change the thread names etc).
Your implementation of the factory is much more complex than is needed though, all you need is:
private final static class ProcessPriorityThreadFactory implements ThreadFactory {
private final int threadPriority;
public ProcessPriorityThreadFactory(int threadPriority) {
this.threadPriority = threadPriority;
}
#Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setPriority(threadPriority);
return thread;
}
}
Related
I have a singleton class thus
public final class HandlerCache {
//the cache maintains a handler per thread
private final Map<Thread, Handler> cache = new ConcurrentHashMap<>();
private final Thread monitor;
private static final HandlerCache INSTANCE = new HandlerCache();
private HandlerCache() {
monitor = new Thread() {
//periodically monitor cache and close handlers when a thread has died
}
monitor.start()
}
public static HandlerCache getInstance() {
return INSTANCE;
}
public Handler getHandler() throws Exception {
final Thread thread = Thread.currentThread();
Handler handler = cache.get(thread);
if (!(handler == null))
return handler;
handler = HandlerFactory.get(getHandlerFromName(thread.getName()));
cache.put(thread, handler);
return handler;
}
}
I am leaking the singleton instance to the monitor thread before the constructor is finished, what is the better way ?
Will making cache volatile will fix the issue ?
As mentioned by user2677485, you should be using a ThreadLocal and implement the initialValue method. The other point is that the Handler implementation should implement the finalize method so that when it is being reclaimed by the GC this method will be called and you can clean up your resources.
The code can be simplified as something like the following:
public class HandlerCache {
private static final handlers = new ThreadLocal<Handler>() {
protected Handler initializeValue() {
return HandlerFactory.get(...);
}
};
public static Handler getHandler() {
return handlers.get();
}
}
Rather than starting the thread within the HandlerCache constructor, you could initialize the instance using a static function that would first construct the HandlerCache and then start the thread.
I have a simple handling of tasks on a separate thread.
class MyHandlerThread extends Thread {
Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}
How can I determine if the looper is currently busy handling messages or its message queue is empty and it is waiting for messages?I want to do that from another thread.
Basically, I want to know when the handler is done with a task that I have just submitted.
You can use synchronized method to determine if thread is busy or not
Example:
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
For More: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
I'm using ScheduledThreadPoolExecutor and I don't know hot to deal with something.
I'm scheduling some tasks this way:
scheduledExecService = new ExtendedScheduledExecutor(numThreads, myThreadFactory);
TareaActualizacion act = new TareaActualizacion(inst);
ScheduledFuture<?> handle = scheduledExecService.scheduleWithFixedDelay(act, retrasoInicial, segundosRefresco, TimeUnit.SECONDS);
act is a Runnable class that recive some data by parameter:
public class TareaActualizacion implements Runnable {
private Instalacion instalacion;
public TareaActualizacion(Instalacion instalacion) {
this.instalacion = instalacion;
}
#Override
public void run() {
//Do something
}
public Instalacion getInstalacion() {
return instalacion;
}
}
Now in the afterExecute method of the ExtendedSecheduledExecutor I want to get the object Instalacion of the task TareaActualizacion but I don't know how to do it.
My ExtendedScheduledExecutor class looks like this:
public class ExtendedScheduledExecutor extends ScheduledThreadPoolExecutor{
public ExtendedScheduledExecutor(int arg0) {
super(arg0);
}
public ExtendedScheduledExecutor(int arg0, ThreadFactory arg1) {
super(arg0, arg1);
}
#Override
protected void afterExecute(Runnable r, Throwable t)
{
super.afterExecute(r, t);
System.out.println("Executing afterExecute. Throwable is " + t);
if (t != null)
t.printStackTrace();
//I need to get the Instalacion attribute from TareaActualizacion task. How can I do it??
}
}
Any idea of how can I solve it??
Thank you!
Neus
As Stephan already pointed out in https://stackoverflow.com/a/22145530 , you should try to decouple the scheduling and execution from the notification.
One approach for this could be to wrap the actual task (TareaActualizacion) into another implementation of the Runnable interface that only executes the actual task, and afterwards notifies a callback about the task that has been executed.
Depending on your precise requirements, there may be several degrees of freedom for the implementation, but a general approach could roughly look like this:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledTaskNotification
{
public static void main(String[] args) throws Exception
{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
int n = 3;
for (int i = 0; i < n; i++)
{
UpdateTask updateTask = new UpdateTask(i);
RunnableCallback<UpdateTask> callback = new RunnableCallback<UpdateTask>()
{
#Override
public void runnableFinished(UpdateTask updateTask)
{
System.out.println("Finished "+updateTask+", id "+updateTask.getID());
}
};
Runnable runnableWithCallback =
createRunnableWithCallback(updateTask, callback);
executor.scheduleWithFixedDelay(
runnableWithCallback, 1000, 200+i*200,
TimeUnit.MILLISECONDS);
}
}
static interface RunnableCallback<T extends Runnable>
{
void runnableFinished(T runnable);
}
private static <T extends Runnable> Runnable createRunnableWithCallback(
final T runnable, final RunnableCallback<T> callback)
{
return new Runnable()
{
#Override
public void run()
{
runnable.run();
callback.runnableFinished(runnable);
}
};
}
private static class UpdateTask implements Runnable
{
private final int id;
UpdateTask(int id)
{
this.id = id;
}
#Override
public void run()
{
System.out.println("Run "+this);
}
int getID()
{
return id;
}
#Override
public String toString()
{
return "UpdateTask "+id;
}
}
}
This is a bay way. You should not trying to get the result out of the Executor, because it is only responsible for scheduling and executing tasks, not whats happening inside of them.
Your TareaActualizacion runnable should post the result to another piece of code, where you need it. This can be achieved using a queue or in the easiest case SwingUtilities.invokeLater().
How to set the Thread priority of a Timer in java? This is the code I have found in the project that I am working on, and I do not think that it is working:
public static Timer createNamedTimer(boolean isDaemon,
final String threadName, final int priority) {
Timer timer = new Timer(isDaemon);
timer.schedule(new TimerTask() {
public void run() {
Thread.currentThread().setName("TimerThread: " + threadName);
Thread.currentThread().setPriority(priority);
}
}, 0);
return timer;
}
AFAIK for timer the only way you can change priority is the way you are doing it.
If you need a better option you can use the ThreadFactory for creating the threads and setting their priority.
class SimpleThreadFactory implements ThreadFactory {
private int threadPriority;
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setPriority(threadPriority);
return t;
}
}
Then you can pass the factory to the Executors framework of Java for doing what you want, IMHO this will be a much better approach.
Why do I say it would be a better approach?
The Timer class's JavaDoc mentions ScheduledThreadPoolExecutor and notes, that this class is effectively a more versatile replacement for the Timer/TimerTask combination
The suggested solution won't likely work for tasks that are repeated more than once, because between invocations another task that shared the same thread may have adjusted the priority to something else. Therefore, for repeating tasks you must set the priority at execution time, every time. This potential issue exists w/or w/o the new Executors framework.
One solution is to create a wrapper class that does prep work for you to ensure consistency. For example:
AnyClass.java:
private static void exampleUsage()
{
try { launchHighPriorityTask(() -> System.out.println("What a fancy task.")).join(); }
catch (Throwable ignored) {}
}
private static Thread launchMaxPriorityTask(Runnable task)
{
final Thread customThread = new Thread(new Task("MaxPriority", Thread.MAX_PRIORITY, task));
customThread.start();
return customThread;
}
Task.java:
public class Task implements Runnable
{
private final String name;
private final int priority;
private final Runnable task;
public Task(String name, int priority, Runnable task)
{
if (null == task) throw new NullPointerException("no task provided");
this.name = name; this.priority = priority; this.task = task;
}
/**
* run() is made final here to prevent any deriving classes
* accidentally ruining the expected behavior
*/
#Override public final void run()
{
final Thread thread = Thread.currentThread();
// cache the current state to restore settings and be polite
final String prevName = thread.getName();
final int prevPriority = thread.getPriority();
// set our thread's config
thread.setName(name);
thread.setPriority(priority);
try { task.run(); } catch (Throwable ignored) {}
// restore previous thread config
thread.setPriority(prevPriority);
thread.setName(prevName);
}
}
This is naturally a minimalist example of what can be accomplished with this sort of setup.
I'm trying to access and modify a variable of a thread in another thread in java, and I really don't know how to do this.
ex :
Runnable r1 = new Runnable() {
int value = 10;
public void run() {
// random stuff
}
}
Runnable r2 = new Runnable() {
public void run() {
// of course the bellow line will not work
r1.value--; // I want here to be able to decrement the variable "value" of r1
}
}
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
Is there any way to create a getter and setter for a thread in java?
Edit: the answers were good, but I was not clear in my question, I will try asking a better question
You could make it sort of work but, I suggest you use an AtomicInteger which is shared between threads.
final AtomicInteger value = new AtomicInteger(10);
Runnable r1 = new Runnable() {
public void run() {
// random stuff using value
}
}
Runnable r2 = new Runnable() {
public void run() {
value.decrementAndGet();
}
}
You can use AtomicReference for references to objects.
Create a runnable, and use the setters and getters you define in said runnable.
public class MyRunnable implements Runnable{
private volatile String myString;
public String setString(String value){this.myString = value;}
public String getString(){
return myString;
}
public void run(){}
}
Note volatile keyword is used here. The volatile keyword ensures if this String changes in one thread, that all threads will see the change. If instead I ensure that the only access to the String object is through synchronized context, then the volatile keyword would not be necessary.
To demonstrate my point, the above code and the below code are both thread-safe but are different as no 2 threads can enter setString and getString simultaneously in the example below.
public class MyRunnable implements Runnable{
private String myString;
public synchronized String setString(String value){this.myString = value;}
public synchronized String getString(){
return myString;
}
public void run(){}
}
A thread is really just executing a runnable. You could use this like so:
MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();
Using atomic values for primitives is fine, but if you ever want to share a more complex object, you'll have to read about threading and synchronization.
For example:
public class Stats{
int iterations;
long runtime;
public Stats(){
iterations = 0;
runtime=0;
}
public synchronized void setIterations(int value){this.iterations = value;}
public synchronized void setRuntime(long milliseconds){
this.runtime = milliseconds;
}
public synchronized int getIterations(){
return iterations;
}
public synchronized long getRuntime(){return runtime;}
}
public class StatRunnable implements Runnable{
Stats stats;
boolean active;
public StatRunnable(){
this.active=true;
}
public Stats getStats(){
return stats;
}
long calculateRuntime(){return 0L;}
public void run(){
while(active){
//i'm synchronizing with stats to ensure no other thread alters values
//simultaneously.
synchronized(stats){
stats.setIterations(stats.getIterations()+1);
stats.setRuntime(calculateRuntime());
}
}
}
}
This code shows an example of synchronization with non-primitive objects via the synchronized keyword. Using the synchronized keyword in a method definition locks the class using itself as the synchronizing object.
A final note, the synchronized keyword isn't just used in method definitions. You can use it to synchronize on instances within methods as I've done in the run method in StatRunnable.