Can someone explain me how to refactor the below code. Basically i have a timer functionality which i am using repeatedly. So i want to put that timer into a generic function.
import java.util.Timer;
import java.util.TimerTask;
public class App {
private volatile boolean a = false;
private volatile boolean b = false;
private volatile boolean c = false;
public static void main(String[] args) {
App app = new App();
app.m1();
}
private void m1() {
// m2() should not take more than specified time in timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if(a){
System.out.println("m1 Do nothing");
}
else{
System.out.println("m1 Timeout exception");
}
}
}, 2*60*1000);
a=m2();
System.out.println("Blah");
}
private boolean m2() {
// Killing some time with sleep
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//m3() should not take more than specified time in timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if(b){
System.out.println("m2 Do nothing");
}
else{
System.out.println("m2 Timeout exception");
}
}
}, 1*60*1000);
b = m3();
System.out.println("Blah Blah");
return true;
}
private boolean m3() {
//m4() should not take more than specified time in timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if(c){
System.out.println("m3 Do nothing");
}
else{
System.out.println("m3 Timeout exception");
}
}
}, 20000);
c=m4();
System.out.println("Blah Blah Blah");
return true;
}
private boolean m4() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
}
Thank you for your help. I am not looking for code help. Want to know your thoughts on minimizing the code.
Related
There is something wrong with my code. The timer overall seems to be working fine and the pause button does its job.
The problem is when you pause the clock at a specific time and then you unpause it.
If we (let's say) pause it at 8 seconds and we unpause it after a minute, it doesn't keep going like 9-10-11, etc. It goes 74-75-76... (I've broken it into minutes and seconds).
Is it a thread that causes the problem? (Also, I've overused freeze_sec and freeze_min time code snippets just to see if it would be fixed but it wasn't.)
Here is the code:
Thread t1 = null;
ss = new ServerSocket(6800);
while(true) {
s = ss.accept();
isr = new InputStreamReader(s.getInputStream());
br = new BufferedReader(isr);
message = br.readLine();
if (message.equals("START")) {
t1 = new Thread(new Thread1());
t1.start();
...
} else if (message.equals("PAUSE")) {
if(check) {
try {
check = false;
Thread1.PAUSE(true);
} catch (Exception e) {
System.out.println("Exception e");
}
} else {
check = true;
Thread1.PAUSE(false);
}
}
And Thread1 class looks like:
import java.io.*;
import java.util.Date;
import java.util.Scanner;
public class Thread1 extends MyServerFrame implements Runnable{
private static int current_min_time = 0;
private static int current_sec_time = 0;
private static int freeze_min_time = 0;
private static int freeze_sec_time = 0;
private static boolean pause = false;
private static int minutes = 0;
private int total_time_sec = 0;
private static boolean freeze_signal = false;
private static int k = 0;
#Override
public void run() {
long elapsedTime = 0L;
boolean bool = true;
int num = 0;
while (bool) {
Scanner scan = new Scanner(System.in);
if (minutes == 0) {
System.out.println("How many minutes for this half-time?");
Scanner in = new Scanner(System.in);
num = in.nextInt();
minutes = num;
}
long startTime = System.currentTimeMillis();
while (total_time_sec < minutes * 60 || freeze_signal == false) {
if (freeze_signal && k == 0) {
freeze_sec_time = current_sec_time;
freeze_min_time = current_min_time;
k++;
}
if (!pause) {
//perform db poll/check
if (elapsedTime / 1000 != current_sec_time) {
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
k = 0;
}
current_sec_time++;
total_time_sec = current_sec_time + current_min_time / 60;
print_in_txt();
}
elapsedTime = (new Date()).getTime() - startTime;
if (current_sec_time == 60) {
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
k = 0;
}
current_sec_time = 0;
current_min_time++;
total_time_sec = current_sec_time + current_min_time / 60;
startTime = System.currentTimeMillis();
elapsedTime = (new Date()).getTime() - startTime;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
}
}
}
}
}
public static void clearTheFile(String txt_name) throws IOException {
try {
FileWriter fwOb = new FileWriter(txt_name, false);
PrintWriter pwOb = new PrintWriter(fwOb, false);
pwOb.flush();
pwOb.close();
fwOb.close();
} catch (IOException e) {}
}
public static void print_in_txt() {
PrintWriter out;
try {
out = new PrintWriter("Half_Time.txt");
out.println(String.format("%02d", current_min_time) + ":" + String.format("%02d", current_sec_time));
out.print("");
out.close();
} catch (FileNotFoundException e) {
System.err.println("File doesn't exist");
e.printStackTrace();
}
}
public static void PAUSE(boolean p) {
if (p) {
pause = true;
freeze_signal = true;
} else {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
pause = false;
freeze_signal = false;
}
}
}
So, after spending some time bagging my head against the idea, I suddenly realised that you don't actually need the thread at all.
What you need is a way to calculate the duration between to points in time, which doesn't need a thread to update the state, it's done automatically.
The thread is just doing "other stuff"
So, based on that, I took a StopWatch class from one of my previous answers...
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
And applied so it could be used within a Thread, which would simply print the running time.
Around this, I added the ability to pause, resume and stop the thread so as to demonstrate the basic idea...
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
#Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
Runnable example...
This basically takes the code from above and dumps it into a simple runnable example which demonstrates the pause/resume functionality
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class StopWatchExample {
public static void main(String[] args) throws InterruptedException {
new StopWatchExample();
}
public StopWatchExample() throws InterruptedException {
StopWatchRunnable stopWatch = new StopWatchRunnable();
Thread thread = new Thread(stopWatch);
thread.start();
Thread.sleep(5000);
System.out.println("Pause...");
stopWatch.pause();
Thread.sleep(5000);
System.out.println("Resume...");
stopWatch.resume();
Thread.sleep(5000);
System.out.println("Stop...");
stopWatch.stop();
thread.join();
System.out.println("All done...");
}
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
#Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
}
Here is my example code.
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
//i ll do some thing here
if(a.flag == true)System.out.println("Kaboom");
}
}
public static void main(String[] args)
{
B b = new B();
}
}
So the thing is i start b before a and i want b to wait until a.flag == true to fire "Kaboom" and a.thr have to wait when b doing its work in run() method. I tried this but it doesnt work
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
synchronized(B.class){
this.flag=true;
B.class.notifyAll();
}
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
synchronized(this){
while(a.flag!=true)
{
this.wait();
}}
}
}
public static void main(String[] args)
{
B b = new B();
}}
There must be a problem in my synchronized block but i dont know what.
This probably a stupid question but i'm just a beginner in JAVA and i dont really get those Thread stuff and how it work. Plz help me
I like your original approach of using wait / notifyAll to make the Thread doesn't use the CPU until the condition is met for it to resume running. Here's a solution that keeps this approach.
A few notes:
1 - Be careful when synchronizing on a class object. Unless you really want to synchronize the whole class, create an Object and use it as a lock.
2 - Use the volatile keyword to ensure that Java doesn't create a thread local version of the variable and that changes to it's value are instantly reflected to other threads.
public class Threads {
private final Object lock = new Object();
private volatile boolean flag;
class RunnableA implements Runnable {
private volatile boolean condition = false;
#Override
public void run() {
while (true) {
if (condition) {
if (!flag) {
synchronized (lock) {
System.out.println("Setting Flag to True");
flag = true;
lock.notifyAll();
}
}
} else {
System.out.println("Condition is False");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
}
}
class RunnableB implements Runnable {
#Override
public void run() {
while (true) {
while (flag == false) {
synchronized (lock) {
if (flag == false) {
try {
lock.wait();
} catch (InterruptedException ex) {
}
}
}
}
System.out.println("Kaboom");
}
}
}
public void run() {
RunnableA runnableA = new RunnableA();
RunnableB runnableB = new RunnableB();
Thread t1 = new Thread(runnableA);
Thread t2 = new Thread(runnableB);
t1.start();
t2.start();
try {
Thread.sleep(5000L);
} catch (InterruptedException ex) {
}
runnableA.condition = true;
}
public static void main(String[] args) {
new Threads().run();
}
}
You created a Runnable but did not start it in a thread.
Proper one:
import java.lang.*;
import java.util.concurrent.atomic.*;
class A implements Runnable {
AtomicBoolean flag;
AtomicBoolean condition;
A() {
flag = new AtomicBoolean();
condition = new AtomicBoolean();
}
public void run(){
while (true) {
System.out.println("A");
if (condition.get()) {
flag.set(true);
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable {
A a;
B() {
a = new A();
}
public void run() {
while (true) {
System.out.println("B");
if (a.flag.get()) {
System.out.println("Kaboom");
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
new Thread(b.a).start();
b.a.condition.set(true);
}
}
Is there a better way to do this? This is for a Kegel app I'm making, nobody wants the drips when they get older, right?! I've tried using this in a for loop, but it only cycles once. :( Now I'm just typing more because the site won't let me post because it says it looks like my post is mostly code.
public final void onClick(View view) {
switch (view.getId()) {
case R.id.tvBeginner:
tvBeginner.setText("Beginner exercise in progress...");
Runnable clenchRunnable = new Runnable() {
#Override
public void run() {
try {
tvExpert.setText("");
tvIntermediate.setText("Clench!!!");
tvIntermediate.setTextSize(60);
vibrate.vibrate(250);
clenchDone = true;
} catch (Exception e) {
e.printStackTrace();
}
}
};
Runnable relaxRunnable = new Runnable() {
#Override
public void run() {
try {
tvIntermediate.setText("");
tvExpert.setText("Relax...");
tvExpert.setTextSize(40);
tvExpert.setTextColor(Color.GREEN);
vibrate.vibrate(250);
clenchDone = false;
} catch (Exception e) {
e.printStackTrace();
}
}
};
clenchHandler.postDelayed(clenchRunnable, 1000);
relaxHandler.postDelayed(relaxRunnable, 2000);
clenchHandler.postDelayed(clenchRunnable, 3000);
relaxHandler.postDelayed(relaxRunnable, 4000);
clenchHandler.postDelayed(clenchRunnable, 5000);
relaxHandler.postDelayed(relaxRunnable, 6000);
clenchHandler.postDelayed(clenchRunnable, 7000);
relaxHandler.postDelayed(relaxRunnable, 8000);
clenchHandler.postDelayed(clenchRunnable, 9000);
relaxHandler.postDelayed(relaxRunnable, 10000);
clenchHandler.postDelayed(clenchRunnable, 11000);
relaxHandler.postDelayed(relaxRunnable, 12000);
clenchHandler.postDelayed(clenchRunnable, 13000);
relaxHandler.postDelayed(relaxRunnable, 14000);
clenchHandler.postDelayed(clenchRunnable, 15000);
relaxHandler.postDelayed(relaxRunnable, 16000);
clenchHandler.postDelayed(clenchRunnable, 17000);
relaxHandler.postDelayed(relaxRunnable, 18000);
clenchHandler.postDelayed(clenchRunnable, 19000);
relaxHandler.postDelayed(relaxRunnable, 20000);
break;
You could call the relaxHandler, clenchHandler inside their respective runnables and keep a counter of the number of times you want to call it ie:
int i =0;
Runnable relaxRunnable = new Runnable() {
#Override
public void run() {
try {
tvIntermediate.setText("");
tvExpert.setText("Relax...");
tvExpert.setTextSize(40);
tvExpert.setTextColor(Color.GREEN);
vibrate.vibrate(250);
clenchDone = false;
} catch (Exception e) {
e.printStackTrace();
}
if(i <= numTimesToRun) {
relaxHandler.postDelayed(relaxRunnable, time_out_variable);
i++;
}
}
};
and then do the same with the clenchHandler so it runs x amount of times
In the mood for coding, so I'm going to take a crack at it...
private static final int SWITCH_DELAY = 1000;
private Handler handler;
private boolean beginnerCycleActive = false;
private boolean clenched = false;
public final void onClick(View view) {
switch (view.getId()) {
case R.id.tvBeginner:
startBeginnerCycle();
break;
}
}
private void startBeginnerCycle(){
beginnerCycleActive = true;
tvBeginner.setText("Beginner exercise in progress...");
doCycle();
}
private void stopBeginnerCycle(){
beginnerCycleActive = false;
}
private void doCycle(){
onClench();
handler.postDelayed(new Runnable(){
public void run(){
onRelax();
handler.postDelayed(new Runnable(){
public void run(){
if(beginnerCycleActive) doCycle();
}
}, SWITCH_DELAY);
}
}, SWITCH_DELAY);
}
private void onClench(){
try {
tvExpert.setText("");
tvIntermediate.setText("Clench!!!");
tvIntermediate.setTextSize(60);
vibrate.vibrate(250);
clenched = true;
}
catch (Exception e) {
e.printStackTrace();
}
}
private void onRelax(){
try {
tvIntermediate.setText("");
tvExpert.setText("Relax...");
tvExpert.setTextSize(40);
tvExpert.setTextColor(Color.GREEN);
vibrate.vibrate(250);
clenched = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
Much cleaner to look at with no repetition and can easily be stopped by calling stopBeginnerCycle()
You should take a look at ScheduledThreadPoolExecutor. It can be use to run Runnable at fixed time with looop period. Example below will show you how it work.
class YourRunnable implements Runnable {
#Override
public void run() {
//Do your stuff
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 10000; // the period between successive executions
exec.scheduleAtFixedRate(new YourRunnable (), 0, duration, TimeUnit.MICROSECONDS); // It can be seconds, miliseconds...
I think it's very easy to use ScheduledThreadPoolExecutor in your case.
Call postDelayed again in the runnable.
I have a simple GUI in which there are two buttons: Print and Stop.
When the user presses print, an already saved number is printed continuously in a loop.
When the user presses Stop, the printing stops.
I am handling the printing of the number in a separate thread, because I need the thread to sleep for a millisecond before printing again.
printBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Thread a= new Thread(new Runnable(){
public void run(){
textArea.setText("");
for (int i=0; i<10; i++){
int result= 0;
System.out.println(result+"\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
a.start();
}
});
Now in the ActionListener of the Stop button, I want the first thread to be interrupted or stopped. How can I do that, since it needs to be interrupted from another thread?
If your first thread contains no Thread-blocking operation, you could for example check for a flag in the for-loop which gets set to true when you press the "Stop"-button.
public class WriterThread implements Runnable {
private volatile boolean stopped = false;
public synchronized void stop() {
this.stopped = true;
}
public void run(){
textArea.setText("");
for (int i=0; i<10; i++) {
if (this.stopped) {
break;
}
int result= 0;
System.out.println(result+"\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
Use AtomicBoolean as flag. It will ensure the thread safety.
Runnable r= new Runnable(){
private AtomicBoolean stop= new AtomicBoolean(false);
public void run(){
for(...){
if(stop.get()){
break; // break the loop
}
...
}
}
public stop(){
stop.set(true);
}
}
Thread a= new Thread(r);
a.start();
r.stop();
final Thread a= new Thread(new Runnable(){
public void run(){
try {
textArea.setText("");
for (int i=0; i<10; i++){
int result= 0;
System.out.println(result+"\n");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// ignore
}
}
});
printBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
a.start();
}
});
stopBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if( a.isAlive() ) {
a.interrupt();
}
}
});
I want to make dialog box to be shown while I load some data from the web service
I'm using the LWUIT,
The following is the code
public class LoaderAnimation extends Container implements Runnable {
private Thread t;
private boolean running = false;
public LoaderAnimation() {
}
public void start() {
running = true;
t = new Thread(this);
t.start();
}
public void run() {
while (running) {
// do something
t.sleep(150);
}
}
public void stop() {
running = false;
}
}
what happens now that it runs but the code of calling the web service has stop working
that is the calling of it
public static void showLoaderScreen ()
{
dialog = new Dialog();
dialog.setLayout(new BorderLayout());
canvas = new LoaderAnimation();
dialog.addComponent(BorderLayout.CENTER , canvas);
canvas.start();
dialog.show();
}
public static void dismissLoaderScreen ()
{
canvas.stop();
dialog.dispose();
}
try this piece of code.
private void startLoader() {
Dialog d = new Dialog();
d.getStyle().setBgColor(0xffffff);
d.getStyle().setBgTransparency(255);
d.show(100, 250, 90, 150, true, false);
d.setAutoDispose(true);
try {
Thread.sleep(30);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
d.dispose();
new Timer().schedule(new TimerTask() {
public void run() {
new Loader().start();
}
}, 30);
}
Loader class we can write parsing stuff or web service handling etc.
class Loader extends Thread
{ public void run() {
try {
ServiceTypesScreen st = new ServiceTypesScreen();
st.init();
} catch (Exception e) {
e.printStackTrace();
}
}
}