I have a scheduled method with integer values with conditions and also have long values for checking these conditions, My code is working however I would like to make a thread safe for long values, I have found AtomicInteger but I do not know how to apply on my code;
My code below;
Yaml file;
listenForInfo: 20000
listenForWarn: 30000
listenForError: 40000
listenScheduled: 1000
My main code;
#Value("${listenForInfo}")
private int listenForInfo;
#Value("${listenForWarn}")
private int listenForWarn;
#Value("${listenForError}")
private int listenForError;
private long lastReceivedMessage = System.nanoTime();
#KafkaListener(topics = "#{'${kafka.topic}'}", groupId = "#{'${kafka.groupid}'}")
public void consume(String message, #Header(KafkaHeaders.RECEIVED_PARTITION_ID) Integer partition,
#Header(KafkaHeaders.OFFSET) Long offset, Acknowledgment ack) {
logger.info("offset = {} ", offset);
logger.info("partition = {} ", partition);
logger.info("kafka Message : {}", message);
lastReceivedMessage = System.nanoTime();
try {
service.processMessage(message, ack, null);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
#Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 1000)
private void distanceBetweenLastReceivedMessageAndCurrentTime() {
long currentTime = (System.nanoTime() - lastReceivedMessage) / 1000000;
logger.info("current time : {}", currentTime);
if (currentTime >= listenForInfo && currentTime < listenForWarn) {
EventUtil.publishEvent("event info ", EventSeverityStatus.INFO, EventTypeStatus.CUSTOM, null);
}
if (currentTime >= listenForWarn && currentTime < listenForError) {
EventUtil.publishEvent("event warn ", EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
}
if (currentTime >= listenForError) {
EventUtil.publishEvent("event error ", EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);
}
}
Related
I`m currently trying to obtain a CountDownTimer based on the time in milliseconds of a Calendar object. The startTimer function works, so does the timerSort function. The thing is that when the timer gets initialized with the timeLeft value, it never start from a value lower than 60 seconds. This eventually causes delays bigger than 10 seconds. any suggestions?
Thank you.
Code:
private void startTimer(String x){
counter = new CountDownTimer(timeLeft,1000) {
#Override
public void onTick(long millisUntilFinished) {
timeLeft = millisUntilFinished;
updateCountdownText();
}
#Override
public void onFinish() {
timerRunning = false;
int comp = Integer.parseInt(x);
Toast.makeText(getApplicationContext(), "Alarm received!", Toast.LENGTH_LONG).show();
cal[comp].add(Calendar.MINUTE,rec[comp]);
//Update txt file
int month = cal[comp].get(Calendar.MONTH)+1;
int day = cal[comp].get(Calendar.DAY_OF_MONTH);
String data = cal[comp].get(Calendar.HOUR_OF_DAY) + ","
+cal[comp].get(Calendar.MINUTE) + ","
+day+ "," + month + ","
+cal[comp].get(Calendar.YEAR) + "," + rec[comp] + ",";
try {
FileOutputStream stream = new FileOutputStream(file[comp], false);
try {
stream.write(data.getBytes());
}catch (Exception e){
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//end update
timerSort();
BluetoothGattCharacteristic C = btper.getCharacteristic(UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"),UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"));
//If device is disconnected => it will crash
btper.writeCharacteristic(C , x.getBytes(StandardCharsets.UTF_8), WriteType.WITH_RESPONSE);
speak(String.valueOf(comp+1));
}
}.start();
}
private void updateCountdownText() {
if(counterView.getVisibility() != View.VISIBLE)
counterView.setVisibility(View.VISIBLE);
int minutes = (int)timeLeft / 1000 / 60;
int seconds = (int)timeLeft /1000 % 60;
String timeLeftFormatted = String.format(Locale.getDefault(),"Time left until next pill: %02d:%02d",minutes,seconds);
if(timeLeftFormatted.contains("00:00"))
counterView.setVisibility(View.INVISIBLE);
counterView.setText(timeLeftFormatted);
}
private void resetTimer(){}
private void timerSort(){
Context context = getApplicationContext();
int i,j;
j = 0;
int fileindex = 0;
int hour, day, month, minute, year;
calendar = Calendar.getInstance();
timeLeft = 0;
for (i = 0; i<20; i++){
fileindex = i+1;
file[i] = new File(context.getExternalFilesDir(null).getAbsolutePath(),"pills"+fileindex+".txt");
cal[i] = (Calendar) calendar.clone();
//Read text from pills file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file[i]));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
}
String str = text.toString();
List<String> elephantList = Arrays.asList(str.split(","));
hour = Integer.parseInt(elephantList.get(0));
minute = Integer.parseInt(elephantList.get(1));
day = Integer.parseInt(elephantList.get(2));
month = Integer.parseInt(elephantList.get(3));
year = Integer.parseInt(elephantList.get(4));
rec[i] = Integer.parseInt(elephantList.get(5));
cal[i].set(Calendar.HOUR_OF_DAY, hour);
cal[i].set(Calendar.MINUTE, minute);
cal[i].set(Calendar.DAY_OF_MONTH, day);
cal[i].set(Calendar.MONTH-1, month);
cal[i].set(Calendar.YEAR,year);
}
// sorting:
int letsgo = 0;
Calendar tudor = Calendar.getInstance();
tudor.set(Calendar.YEAR,calendar.getMaximum(Calendar.YEAR));
for (i = 0; i<20; i++){
if(tudor.after(cal[i]) && cal[i].after(calendar)){
tudor = cal[i];
letsgo = i;
}
}
Toast.makeText(getApplicationContext(), String.valueOf(letsgo), Toast.LENGTH_LONG).show();
TextView nextPillView = (TextView) findViewById(R.id.nextPillView);
if (!cal[letsgo].after(calendar)) {
nextPillView.setText("No Pills Scheduled");
} else {
// timeLeft = cal[letsgo].getTimeInMillis() - calendar.getTimeInMillis() - Calendar.MILLISECOND;
int secleft = cal[letsgo].get(Calendar.SECOND)-calendar.get(Calendar.SECOND);
int minleft = cal[letsgo].get(Calendar.MINUTE)-calendar.get(Calendar.MINUTE);
timeLeft = secleft*1000 + minleft*60*1000 ;
//timeLeft = cal[letsgo].getTimeInMillis() - calendar.getTimeInMillis();
String theTime = String.format(Locale.getDefault(), "%02d:%02d", cal[letsgo].get(Calendar.HOUR_OF_DAY), cal[letsgo].get(Calendar.MINUTE));
month = cal[letsgo].get(Calendar.MONTH)+1;
nextPillView.setText(cal[letsgo].get(Calendar.HOUR_OF_DAY)+":"+cal[letsgo].get(Calendar.MINUTE)+ " | | Day: " + cal[letsgo].get(Calendar.DAY_OF_MONTH) + " | | Month: " + String.valueOf(month) + " | | Year: " + cal[letsgo].get(Calendar.YEAR));
startTimer(String.valueOf(letsgo));
}
}
private void speak(String x){
float pitch = 1;
float speed = 1;
mTTS.setPitch(pitch);
mTTS.setSpeechRate(speed);
mTTS.speak("It is time to administer the compartment with the lit LED",
TextToSpeech.QUEUE_ADD,null);
}
I have some confuse about ReentrantLock tryLock(timeout,timeUnit) method , when
running below code it seems tryLock timeout until the previous thread end,could anyone explains this?
public class MyService2 {
public ReentrantLock lock = new ReentrantLock();
public void waitMethod() {
try {
System.out.println(System.currentTimeMillis() + " " + Thread.currentThread().getName() + " enter ");
boolean b = lock.tryLock(2, TimeUnit.SECONDS);
if (b) {
System.out.println(System.currentTimeMillis() + " lock begin:" + Thread.currentThread().getName());
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
Math.random();
}
System.out.println(System.currentTimeMillis() + " lock end " + Thread.currentThread().getName());
return;
}
System.out.println(System.currentTimeMillis() + " " + Thread.currentThread().getName() + " got no lock end ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
MyService2 myService2 = new MyService2();
Runnable runnable = myService2::waitMethod;
Thread thread1 = new Thread(runnable);
thread1.setName("T1");
thread1.start();
TimeUnit.MILLISECONDS.sleep(10);
Thread thread2 = new Thread(runnable);
thread2.setName("T2");
thread2.start();
}
after running this code ,the result is like that
1555343172612 T1 enter
1555343172613 lock begin:T1
1555343172627 T2 enter
1555343179665 lock end T1
1555343179665 T2 got no lock end
my question is why thread T2 doesn't timeout in 2s rather than waiting until thread T1 ends?
BUT I just found:
if replace Math.random() with TimeUnit.SECONDS.sleep(1) for example ,it works fine.
if run in debug mode ,it works fine too.
Here is an alternate which has a number modifications:
First, cleanups. Clearer names. Less intrusive logging. Relative time values.
Second, the 0.1s sleep between the launch of the two compute threads is moved into each of the threads. That more clearly gives precedence to the thread which launches the compute threads.
Third, the launch thread has joins with the compute threads. That is to tie the conclusion of the computation to the launch thread. In the original code, there is no management of the compute threads after they have been launched. If the compute threads are intended to be unmanaged, that needs to be documented.
Fourth, the entire launch thread plus two compute threads structure is replicated. That is to place give the structure a more realistic runtime environment, and, to present the different behaviors of the structure together in a single view.
A theme to the modifications is to provide clarity, both to the intended behavior of the program, and to the actual behavior (as viewed through the logging output). The goal is to provide maximal clarity to these.
An additional modification is recommended, which is to put the log statements into a cache, then display the collected log lines after all of the computation cells have completed. That removes behavior changes caused by the log statements, which are often considerable.
package my.tests;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private static long initialTime;
protected static void setInitialTime() {
initialTime = System.currentTimeMillis();
}
public static long getInitialTime() {
return initialTime;
}
public static final int CELL_COUNT = 10;
public static void main(String[] args) {
setInitialTime();
System.out.println("Beginning [ " + Integer.toString(CELL_COUNT) + " ] computation cells");
Thread[] cellThreads = new Thread[CELL_COUNT];
for ( int cellNo = 0; cellNo < CELL_COUNT; cellNo++ ) {
final String cellNoText = Integer.toString(cellNo);
Runnable computeCell = () -> {
(new LockTest(cellNoText) ).compute();
};
Thread cellThread = new Thread(computeCell);
cellThreads[cellNo] = cellThread;
}
// Start them all up ...
for ( Thread cellThread : cellThreads ) {
cellThread.start();
}
// Then wait for them all to finish ...
for ( Thread cellThread : cellThreads ) {
try {
cellThread.join();
} catch ( InterruptedException e ) {
System.out.println("Unexpected interruption: " + e.getMessage());
e.printStackTrace();
}
}
System.out.println("Completed [ " + Integer.toString(CELL_COUNT) + " ] computation cells");
}
//
public LockTest(String cellName) {
this.cellName = cellName;
}
private final String cellName;
public String getCellName() {
return cellName;
}
// Logging ...
public String formatTime(long timeMs) {
return String.format("%12d (ms)", new Long(timeMs));
}
public long getRelativeTime(long currentTime) {
return currentTime - getInitialTime();
}
public String formatRelativeTime(long timeMs) {
return String.format(
"%12d %8d (ms)",
new Long(timeMs),
new Long( timeMs - getInitialTime() ));
}
public void log(String methodName, String message) {
long timeMs = System.currentTimeMillis();
String threadName = Thread.currentThread().getName();
System.out.println(
formatRelativeTime(timeMs) + ": " +
methodName + ": " +
threadName + ": " + message);
}
//
public void compute() {
log("compute", "ENTER: " + getCellName());
Runnable computation = () -> {
guardedComputation(
100L, 0, // Pause 0.1s before attempting the computation
1, TimeUnit.SECONDS, // Try to obtain the computation lock for up to 1.0s.
Integer.MAX_VALUE / 60 ); // Run this many computations; takes about 2s; adjust as needed
};
Thread computer1 = new Thread(computation);
computer1.setName( getCellName() + "." + "T1");
Thread computer2 = new Thread(computation);
computer2.setName( getCellName() + "." + "T2");
// Run two sets of computations:
//
// Each will pause for 0.1s before performing the computations.
//
// Performing computations requires a computation lock; wait up to 2.0s
// to acquire the lock.
computer1.start();
computer2.start();
try {
computer1.join();
} catch ( InterruptedException e ) {
System.out.println("Unexpected interruption: " + e.getMessage());
e.printStackTrace();
return;
}
try {
computer2.join();
} catch ( InterruptedException e ) {
System.out.println("Unexpected interruption: " + e.getMessage());
e.printStackTrace();
return;
}
log("compute", "RETURN: " + getCellName());
}
// Computation locking ...
private final ReentrantLock computationLock = new ReentrantLock();
public boolean acquireComputationLock(long maxWait, TimeUnit maxWaitUnit) throws InterruptedException {
return computationLock.tryLock(maxWait, maxWaitUnit);
}
public void releaseComputationLock() {
if ( computationLock.isHeldByCurrentThread() ) {
computationLock.unlock();
}
}
//
public void guardedComputation(
long pauseMs, int pauseNs,
long maxWait, TimeUnit maxWaitUnit, int computations) {
String methodName = "guardedComputation";
log(methodName, "ENTER");
try {
Thread.sleep(pauseMs, pauseNs);
} catch ( InterruptedException e ) {
System.out.println("Unexpected interruption: " + e.getMessage());
e.printStackTrace();
return;
}
try {
boolean didLock;
try {
didLock = acquireComputationLock(maxWait, maxWaitUnit);
} catch ( InterruptedException e ) {
System.out.println("Unexpected interruption: " + e.getMessage());
e.printStackTrace();
return;
}
String computationsText = Integer.toString(computations);
if ( didLock ) {
log(methodName, "Starting computations: " + computationsText);
for ( int computationNo = 0; computationNo < computations; computationNo++ ) {
Math.random();
}
log(methodName, "Completed computations: " + computationsText);
} else {
log(methodName, "Skipping computations: " + computationsText);
}
} finally {
releaseComputationLock();
}
log(methodName, "RETURN");
}
}
I am working with websockets, i want the process of sending/recieving data be as fast as possible. I have come across BSON and MsgPack libraries for binary serialization. However, using simple tests:
#Message
class MessageTemplate implements Serializable {
public String msg;
}
public class test {
static void start(){
MessageTemplate x = new MessageTemplate();
for (int i = 0; i < 1000; ++i)
x.msg += UUID.randomUUID().toString();
System.out.println("===============================================================");
{
long startTime = System.nanoTime();
byte[] bytes = SerializationUtils.serialize(x);
MessageTemplate x1 = (MessageTemplate) SerializationUtils.deserialize(bytes);
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("TIME1:" + String.valueOf(duration) + ", SIZE: " + bytes.length);
}
System.out.println("===============================================================");
MessagePack msgpack = new MessagePack();
{
long startTime = System.nanoTime();
try {
byte[] b = msgpack.write(x);
MessageTemplate dst = msgpack.read(b, MessageTemplate.class);
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("TIME1:" + String.valueOf(duration) + ", SIZE: " + b.length);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Output:
starting===============================================================
TIME1:2560388, SIZE: 36171
===============================================================
TIME1:93729732, SIZE: 36013
It seems that serialization is way faster than MsgPack. However searching i have found not any mentioning of java serialization as "serializating library/format".
What are the drawbacks of using it? Why is it or isnt used? The only drawback i see is that mobile app will have ios/android client, so there wont be java on both sides in every case.
Thanks for help and answers.
how to solve the problem in the log cat .. the error says wait time is negative and it crashes on imulator and external device
this is my code in java android activity
public void run() {
long startTime;
long timeMills;
long waitTime;
long totalTime = 0;
int frameCount = 0;
long targetTime = 1000/FPS;
while (running){
startTime = System.nanoTime();
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(canvas != null){
try {
surfaceHolder.unlockCanvasAndPost(canvas);
}catch (Exception e){
e.printStackTrace();
}
}
}
timeMills = (System.nanoTime() - startTime) / 1000000;
waitTime = targetTime - timeMills;
try {
this.sleep(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == FPS){
avrageFPS = 1000 / (totalTime/frameCount) / 1000;
frameCount = 0;
totalTime = 0;
System.out.print(avrageFPS);
}
}
}
and this is the log
java.lang.IllegalArgumentException: millis < 0: -136
Your code does this:
long targetTime = 1000/FPS;
while (...) {
startTime = System.nanoTime();
... do lots of work ...
timeMills = (System.nanoTime() - startTime) / 1000000;
waitTime = targetTime - timeMills;
If the time required to prepare and render a frame exceeds targetTime, then waitTime will be negative. The complexity of your animation, and the value for FPS, affect how likely this is to happen.
The easiest fix is simply:
if (waitTime < 0) { waitTime = 0; }
That way, if your rendering is taking too long and you're missing deadlines, you don't sleep at all.
A better fix would be to structure the game to run off the display's timing, rather than having a fixed notion of frame rate, and to drop frames when you fall behind. More information about this can be found in this appendix to the graphics architecture doc.
I need to display lots of files with filename and icon in my program.
Therefor I am extracting the icons from the files, but it takes too long.
I have tried 2 different methods to extract the icons, but both are really slow (in my case REALLY slow, because I get the files from a networkdrive).
Here is an example, where I extract the icons and count the number of icons (do nothing with the files/icons)
public class Main {
public static void main(String[] args) {
File folder = new File("C:\\Windows\\System32\\");
File[] list = folder.listFiles();
for(int i = 0; i< 3; i++) {
long startTime = System.currentTimeMillis();
System.out.println("Method 1: " + getIconNumber1(list)+ " Icons");
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Finished Method 1 in " + (float) elapsedTime / 1000 + "sec");
long startTime2 = System.currentTimeMillis();
System.out.println("Method 2: " + getIconNumber2(list)+ " Icons");
long stopTime2 = System.currentTimeMillis();
long elapsedTime2 = stopTime2 - startTime2;
System.out.println("Finished Method 2 in " + (float) elapsedTime2 / 1000 + "sec");
System.out.println("-----------------");
}
}
private static int getIconNumber1(File[] list) {
int nr = 0;
for(File f : list) {
try {
ShellFolder sf = ShellFolder.getShellFolder(f);
ImageIcon icon = new ImageIcon(sf.getIcon(true));
nr++;
} catch (Exception e) {
e.printStackTrace();
}
}
return nr;
}
private static int getIconNumber2(File[] list) {
int nr = 0;
for(File f : list){
FileSystemView view = FileSystemView.getFileSystemView();
Icon icon = view.getSystemIcon(f);
nr++;
}
return nr;
}
}
Is there a faster way to do this?