I am (very) very new to Java. The code in question is spawning a thread that performs some action at a specific time. This time is obtained from the main thread that receives it via http://ip:80/time=(int,sec)
Users can call this URL and update this time as many times as they want. This means I have to pass my integer to the thread so that it can run using a given time, such as when it changes. How do I do that?
Here's how my thread is defined and launched:
Thread launchLoadBalancer = new Thread() {
public void run() {
TimerTask timerTask = new TimerTask(serverSocket, //object for extra data);
try {
timerTask.start();
} catch (IOException e) {
}
}
};
launchtimerTask.start();
I have to pass integer from the new TimerTask. I can modify the constructor on the other end. How do I correctly pass integer?
Make a new class that extends Thread and has a constructor that takes an int.
class LaunchLoadBalancerThread extends Thread {
private int i;
public LaunchLoadBalancerThread(int i) {
this.i = i;
}
public void run() {
TimerTask timerTask = new TimerTask(serverSocket, //object for extra data);
try {
timerTask.start();
} catch (IOException e) {
}
}
}
Then, you can use that class (replace i with your number):
Thread launchLoadBalancer = new LaunchLoadBalancerThread(i);
launchLoadBalancer.start();
public class Main {
public static void main(String[] args) {
int length = 1000;
Thread launchLoadBalancer = () -> {
TimerTask timerTask = new TimerTask(serverSocket, length);
try {
timerTask.start();
} catch (IOException e) {
}
};
launchLoadBalancer.start();
}
}
Related
I am trying to print numbers from 1 to 10 in sequence using a shared integer object across multiple threads. When using the shared object as AtomicInteger, the program works correctly, but when using normal Integer objects, the program throws an exception and I don't know why this is happening.
Program with AtomicInteger
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadingProblem {
public static void main(String[] args) {
AtomicInteger sharedInt = new AtomicInteger(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingPrintingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingIncrementingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject.get() < 10) {
this.sharedObject.incrementAndGet();
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Shared object value is: 1
Shared object value is: 2
Shared object value is: 3
Shared object value is: 4
Shared object value is: 5
Shared object value is: 6
Shared object value is: 7
Shared object value is: 8
Shared object value is: 9
Shared object value is: 10
Program with normal Integer object
public class ThreadingProblem {
public static void main(String[] args) {
Integer sharedInt = new Integer(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private Integer sharedObject;
public ThreadingPrintingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private Integer sharedObject;
public ThreadingIncrementingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject < 10) {
this.sharedObject++;
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Exception in thread "IncrementerThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.itiviti.apps.catalys.shared.mock.ThreadingIncrementingTask.run(ThreadingProblem.java:52)
at java.lang.Thread.run(Unknown Source)
this.sharedObject++; does not do what you assumed it would do.
Since Integer is immutable, it can't change the existing shared object. What this operation does instead is unbox the value into an int, increment it, then box it back into a different Integer instance.
So your code is (almost*) equivalent to the following:
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);
As at this point your object is no longer the same instance, your synchronized blocks won't line up with the wait()/notify() calls.
Note that this has got nothing to do with the atomicity of AtomicInteger, it's simply to do with how the ++ operator works on an Integer.
*In reality you might get a cached instance instead of new Integer(), but it will still be a different instance, as it represents a different int value.
I'm doing a thread who tells me when an event happens. I think that thread is not necessary if event can be controlled by timer for example. But I need an event every minute. Trouble are two:
1. When event is inside a thread occurs too fast. It seems like loop over thread. But threads are necessary to listen or catch an event.
2. I can't tell method which custom object must dispatch event, and then capture this event from a new class
I hope that you can help, here is code:
import java.util.Observer;
import java.util.Observable;
public class Main {
public static void main(String[] args) {
Threading test = new Threading();
test.start();
}
}
class ResponseHandler implements Observer {
#Override
public void update(Observable obj, Object arg) {
if (arg instanceof String) {
String resp = (String) arg;
System.out.println("\n Received response: " + resp);
}
}
}
class EventSource extends Observable implements Runnable {
#Override
public void run() {
try {
while (true) {
Object msg = new Object(); //I guess that this must have an object here, that throws a timeout
setChanged();
notifyObservers(msg);
}
} catch (Exception e) { e.printStackTrace();}
}
}
class Obj {
EventSource _eventSource;
ResponseHandler _responseHandler;
public Obj() {
try {
_eventSource = new EventSource();
_responseHandler = new ResponseHandler();
_eventSource.addObserver(_responseHandler);
} catch (Exception ex) {
System.out.print(ex);
}
}
}
class Threading extends Obj implements Runnable {
Thread _thread;
public void run() {
while (true) {
try {
_eventSource.run(); //Event which never stops
Thread.sleep(1000); //hey thread what are you doing?
} catch (InterruptedException ex) {
}
System.out.println("Thread");
}
}
//Singlethon
public void start() {
if (_thread == null) {
_thread = new Thread(this);
_thread.start();
}
}
}
In a web server i wrote, each request invokes a list of actions. Some of these actions aren't as critical as others, so I would like to run them in a background thread.
Also, since they aren't that important I don't care if one of them fails seldomly, and I don't want them to take up a thread forever, so other threads would be available to process the next batch.
So, I would like to have a thread pool (e.g.: 10 threads) and hand out a thread to each background task like this. Limit each thread to 1 second, and if it doesn't finish by that time, just kill it, and be available for the next task to come in.
How would I go about doing this ?
So far, this is what I have :
public class AsyncCodeRunner {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public void Run(Callable<Void> callableCode, int timeout) {
final int threadTimeout = 10;
Future<Void> callableFuture = executor.submit(callableCode);
try {
callableFuture.get(threadTimeout, TimeUnit.SECONDS);
} catch (Exception e) {
logger.Info("Thread was timed out", e);
}
}
}
And I want to use this class like this :
public void processRequest(RequestObject request) {
// do some important processing
// throw some less important processing to background thread
(new AsyncCodeRunner()).Run(new Callable<Void> () {
#Override
public Void call() throws Exception {
// do something...
return null;
}
}, 1); // 1 second timeout
// return result (without waiting for background task)
return;
}
Will this work like I want it to ? Or how should I change it so it would ?
And what happens if I call Run() but there are no available threads in the threadpool to hand out ?
I think your primary problem with this rather elegant idea is that you are only timing out on the get of the Future, you are not actually aborting the process once it times out, you are just giving up waiting for it. The issue becomes even more complex when you realise that you may even time out when the process hasn't even started - it is just still in the queue.
Perhaps something like this would be effective. It does require two threads but a TimerTask thread should consume very little.
public class RunWithTimeout {
public RunWithTimeout(Runnable r, long timeout) {
// Prepare the thread.
final Thread t = new Thread(r);
// Start the timer.
new Timer(true).schedule(new TimerTask() {
#Override
public void run() {
if (t.isAlive()) {
// Abort the thread.
t.interrupt();
}
}
}, timeout * 1000);
// Start the thread.
t.start();
}
}
class WaitAFewSeconds implements Runnable {
final long seconds;
WaitAFewSeconds(long seconds) {
this.seconds = seconds;
}
#Override
public void run() {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ie) {
System.out.println("WaitAFewSeconds(" + seconds + ") - Interrupted!");
}
}
}
public void test() {
new RunWithTimeout(new WaitAFewSeconds(5), 3);
new RunWithTimeout(new WaitAFewSeconds(3), 5);
}
Here's an alternative that only uses one extra thread.
public class ThreadKiller implements Runnable {
DelayQueue<WaitForDeath> kill = new DelayQueue<>();
private class WaitForDeath implements Delayed {
final Thread t;
final long finish;
public WaitForDeath(Thread t, long wait) {
this.t = t;
this.finish = System.currentTimeMillis() + wait;
}
#Override
public long getDelay(TimeUnit unit) {
return unit.convert(finish - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
#Override
public int compareTo(Delayed o) {
long itsFinish = ((WaitForDeath) o).finish;
return finish < itsFinish ? -1 : finish == itsFinish ? 0 : 1;
}
}
#Override
public void run() {
while (true) {
try {
WaitForDeath t = kill.take();
if (t.t.isAlive()) {
// Interrupt it.
t.t.interrupt();
}
} catch (InterruptedException ex) {
// Not sure what to do here.
}
}
}
public void registerThread(Thread t, long wait) {
// Post it into the delay queue.
kill.add(new WaitForDeath(t, wait));
}
}
public void test() throws InterruptedException {
// Testing the ThreadKiller.
ThreadKiller killer = new ThreadKiller();
Thread killerThread = new Thread(killer);
killerThread.setDaemon(true);
Thread twoSeconds = new Thread(new WaitAFewSeconds(2));
Thread fourSeconds = new Thread(new WaitAFewSeconds(4));
killer.registerThread(twoSeconds, 5000);
killer.registerThread(fourSeconds, 3000);
killerThread.start();
twoSeconds.start();
fourSeconds.start();
System.out.println("Waiting");
Thread.sleep(10 * 1000);
System.out.println("Finished");
killerThread.interrupt();
}
You need to start timer when the thread runs. Then no thread in waiting state will be killed. Here is the sample from this thread:
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolTest {
class TimeOutTask extends TimerTask {
Thread t;
TimeOutTask(Thread t) {
this.t = t;
}
public void run() {
if (t != null && t.isAlive()) {
t.interrupt();
}
}
}
class MyRunnable implements Runnable {
Timer timer = new Timer(true);
public void run() {
timer.schedule(new TimeOutTask(Thread.currentThread()), 1000);
try {
System.out.println("MyRunnable...");
Thread.sleep(10000);
} catch (InterruptedException ie) {
System.out.println("MyRunnable error...");
ie.printStackTrace();
}
}
}
public static void main(String args[]) {
new PoolTest();
}
public PoolTest() {
try {
ExecutorService pe = Executors.newFixedThreadPool(3);
pe.execute(new MyRunnable());
} catch (Exception e) {
e.printStackTrace();
}
}
}
What will happen if I assign a new thread object to a thread variable and run it while the thread object that was bound to the variable before is still running? Will it be garbage collected and destroyed? Or will they run in parallel?
Something like this:
class ThreadExample implements Runnable {
public void run() {
// Something that runs for a long time
}
}
public class ThreadExampleMain {
public static void main(String[] args) {
// Client Code
ThreadExample e = new ThreadExample();
Thread t = new Thread(e);
t.start();
e = new ThreadExample();
t = new Thread(e);
t.start();
}
}
Will this start two threads running parallelly or will the first thread stop and be garbage collected?
If you a talking about Java then answer is: they will run in parallel. Garbage collection has nothing to do with the thread management.
You can see it with this sample code:
public class LostThread {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
final int value = i;
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
System.out.println(value);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
}
Main finishes after ten threads are created, but they are still running.
I wrote on my own a set of code to record what I say through a microphone.
I would like to understand the function that google uses for stopping this recording when there is "silence". For example if I go on google and press the microphone symbol, I can say what I plan to look for, but what is the function that it uses to understand the moment when I do not say anything (the moment of "silence")? I thought about doing a cycle in which they are recording some dB or RMS of a few sound frames, and by comparison I can understand if there's "silence".
until now the time is static.
public static void main(String[] args) {
final Main REGISTRAZIONE = new Main();
Thread TIME = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(RECORD_TIME);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
REGISTRAZIONE.finish();
}
});
TIME.start();
REGISTRAZIONE.start();
}
Your approach of checking for dB is good. Then, you can use another Thread to check for silence, and stop the main thread when it finds it. You have to use your own implementation of Thread so that it can take TIME as parameter and stop it when there is silence:
public class Recorder {
static Long RECORD_TIME = 100000L; //or whatever time you use
public static void main(String[] args) {
final Main REGISTRAZIONE = new Main();
Thread TIME = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(RECORD_TIME);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
REGISTRAZIONE.finish();
}
});
TIME.start();
myThread finisher = new myThread(TIME);
finisher.start();
REGISTRAZIONE.start();
}
}
class myThread extends Thread implements Runnable {
private Thread TIME;
public myThread(Thread TIME) {
this.TIME = TIME;
}
public void run() {
while (!silence()) {
// do nothing
}
TIME.interrupt();
}
private boolean silence() {
//record and calculate the dB volume and compare to some level
return true;
}
}