here is the code segment
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
class VolatileTest{
private static boolean stop = false;
public void go() throws Exception{
new Thread(()->{
System.out.println("thread started in " + Thread.currentThread().getName());
int counter = 0;
while (!stop){
counter++;
};
// #1
System.out.println("stopped at i=" + counter + " in " + Thread.currentThread().getName());
}).start();
Thread.sleep(1000);
stop = true;
}
}
#RestController
public class MyVolatileController {
#GetMapping("/volatile/test")
public String test(){
new Thread(()->{
try{
new VolatileTest().go();
}catch(Exception e){}
}).start();
return "volatile";
}
public static void main(String[] args) throws Exception{
new Thread(()->{
try{
new VolatileTest().go();
}catch(Exception e){}
}).start();
}
}
the expected behavior: when called, the program will never reach #1, since stop is not volatile, and the change made by other thread will not been seen immediately by the current thread.
Question: when it is started in public void static main of the class, it behaves as expected, however, when started inside a spring controller method, it does reach #1. why is that happening ?
Related
I’m working on the task of monitoring the execution of query, it became necessary to check the query after a certain time. Please, help me, how to implement the method poll correctly? Is it possible to do this in a separate thread? For example, I want to log every iteration of the loop and end the stream on the number 8. how to implement it correctly? Thanks!
public class MyTimerTask implements Runnable {
String name;
private boolean isActive;
void disable(){
isActive=false;
}
MyTimerTask(String name){
isActive = true;
this.name = name;
run();
}
#Override
public void run() {
System.out.println(name + " Start at :" + new Date());
try {
completeTask();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " Finish at:" + new Date());
}
private void completeTask() throws InterruptedException {
for(int i = 0; i<10;i++){
System.out.println(i);
Thread.sleep(1000);
}
}
public static void main(String args[]){
new MyTimerTask("device");
}
}
Try something like this:
public class MyTimerTask implements Runnable {
#Override
public void run() {
System.out.println(name + " Start at :" + new Date());
completeTask();
System.out.println(name + " Finish at:" + new Date());
}
private void completeTask() throws InterruptedException {
for(int i = 0; i<10;i++){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
new Thread(new MyTimerTask(), "device").start();
}
}
Do not need those fields, java.lang.Thread have those.
Do not call methods from the constructor that requires the instance to be fully created. EG: do not call run() from it.
InterruptedExceptions should be caught, but in this case you may want to swallow it, as it is not signalling an unfinished job...
To create a new thread use the Thread: You can specify the Runnable instance and/or name as arguments of the constructor. Or you can extend it and call super() with the name in the constructor, and implement run() in it.
.
public class MyTimerTask extends Thread {
public MyTimerTask() {
super("device");
}
#Override
public void run() {
System.out.println(name + " Start at :" + new Date());
completeTask();
System.out.println(name + " Finish at:" + new Date());
}
private void completeTask() throws InterruptedException {
for(int i = 0; i<10;i++){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
new Thread().start();
}
}
You implementation works fine.
You just need include on main method:
public static void main(String args[]){
new Thread(new MyTimerTask("device")).start();
}
Have in mind that according this implementation you'll run the function only 10 times.
As you have a status flag maybe you can use it changing the loop intructoin.
while (isActive) {
System.out.println(name + " Start at :" + Instant.now());
I am trying to create a program that will carry on running automatically without me having to do anything. I am a bit confused on how to implement runnable in java so I can create a thread that will go to sleep for a certain period of time and then run the re-run the program after the sleep period is over.
public class work {
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.information();
}
private ConfigurationBuilder OAuthBuilder() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("dy1Vcv3iGYTqFif6m4oYpGBhq");
cb.setOAuthConsumerSecret("wKKJ1XOPZbxX0hywDycDcZf40qxfHvkDXYdINWYXGUH04qU0ha");
cb.setOAuthAccessToken("4850486261-49Eqv5mogjooJr8lm86hB20QRUpxeHq5iIzBLks");
cb.setOAuthAccessTokenSecret("QLeIKTTxJOwpSX4zEasREtGcXcqr0mY8wk5hRZKYrH5pd");
return cb;
}
public void information() throws IOException, InterruptedException {
ConfigurationBuilder cb = OAuthBuilder();
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
User user = twitter.showUser("ec12327");
Query query = new Query("gym fanatic");
query.setCount(100);
query.lang("en");
String rawJSON =null ;
String statusfile = null;
int i=0;
try {
QueryResult result = twitter.search(query);
for(int z = 0;z<5;z++){
for( Status status : result.getTweets()){
System.out.println("#" + status.getUser().getScreenName() + ":" + status.getText());
rawJSON = TwitterObjectFactory.getRawJSON(status);
statusfile = "results" + z +".txt";
storeJSON(rawJSON, statusfile);
i++;
}
}
System.out.println(i);
}
catch(TwitterException e) {
System.out.println("Get timeline: " + e + " Status code: " + e.getStatusCode());
if(e.getErrorCode() == 88){
Thread.sleep(900);
information();
}
}
} catch (TwitterException e) {
if (e.getErrorCode() == 88) {
System.err.println("Rate Limit exceeded!!!!!!");
Thread.sleep(90);
information();
try {
long time = e.getRateLimitStatus().getSecondsUntilReset();
if (time > 0)
Thread.sleep(900000);
information();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
private static void storeJSON(String rawJSON, String fileName) throws IOException {
FileWriter fileWriter = null;
try
{
fileWriter = new FileWriter(fileName, true);
fileWriter.write(rawJSON);
fileWriter.write("\n");
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
} finally {
if(fileWriter!=null) {
fileWriter.close();
}
}
}
}
You have severable options to implement a thread in Java.
Implementing Runnable
When a class implements the Runnable interface, he has to override the run() method. This runnable can be passed to the constructor of a Thread. This thread can then be executed using the start() method. If you'd like to have this thread run forever and sleep, you could do something like the following:
public class HelloRunnable implements Runnable {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Extending Thread
Thread itself also has a run() method. When extending thread, you can override the Thread's run() method and provide your own implementation. Then you'd have to instantiate your own custom thread, and start it in the same way. Again, like the previous you could do this:
public class HelloThread extends Thread {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Source: Oracle documentation
Building on the previous answer, you need to either extend Thread or implement Runnable on your Work class. Extending Thread is probably easier.
public class work extends Thread {
public void run() {
// your app will run forever, consider a break mechanism
while(true) {
// sleep for a while, otherwise you'll max your CPU
Thread.sleep( 1000 );
this.information();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.start();
}
// ... rest of your class
}
public static void main(String[] args){
Thread thread = new Thread(runnable); // create new thread instance
thread.start(); // start thread
}
public static Runnable runnable = new Runnable(){
#Override
public void run(){
final int DELAY = 500;
while(true){
try{
// Code goes here;
Thread.sleep(DELAY)
} catch(Exception e){
e.printStackTrace();
}
}
}
}
I am developing my Spring boot application wich
gets two requests: /start and /stop.
I need to create one shared thread for all clients requests.
When the first request "/start" will be received from client, app will create one thread shared by local variable T1.
When the second request "/stop" will be received, app will set boolean variable of thread "stopped" to stop it and the thread should stop.
Is next code provides safe for this shared thread?
Should i use the local variable for thread object or need to
do it by another way?
package com.direct.webflow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#EnableAutoConfiguration
#Controller
public class WebApp {
ThreadDemo T1;
#RequestMapping("/start")
#ResponseBody
String start() {
synchronized(this){
if (T1 == null || T1.stopped) {
T1= new ThreadDemo( "Thread-1");
T1.start();
} else {
return "Already started!";
}
}
return "Thread started!";
}
#RequestMapping("/stop")
#ResponseBody
String end() {
if (T1 == null) {
System.out.println("Not started!");
return "Not started!";
} else if (!T1.stopped) {
T1.stopped=true;
System.out.println("Trying to stop!");
return "Stopped!";
} else {
return "Already stopped!";
}
}
public static void main(String[] args) throws Exception {
SpringApplication.run(WebApp.class, args);
}
}
package com.direct.webflow;
public class ThreadDemo extends Thread {
private Thread t;
private String threadName;
public volatile boolean stopped=false;
ThreadDemo(String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
int i=0;
System.out.println("Running " + threadName );
while (!stopped) {
System.out.println("Thread: " +this.isInterrupted()+ threadName + ", " + i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Thread: STOP!");
break;
}
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start ()
{
stopped=false;
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
This is very close. You need to add the synchronized(this) block in your controller end() method. Otherwise you may have a race condition if /stop and /start are being called simultaneously.
Since Spring controllers are singletons you are OK to use a member variable like you have done here.
I have a multi-threaded command line app. It is a web service client with a pool of 10 threads that churns away, sending requests, batch-style, to a server.
But it runs for a few days, and sometimes further down the pipeline, the queues start getting backed up. So I want to go to the client, press - or + and have that increase or decrease a Thread.sleep(waitingTime), to take pressure off the server.
I tried running a Scanner in a separate thread, but it didn't seem to work. Has anyone managed to get non-blocking I/O working in Java? I presume it's possible, but I'm giving up for now.
Edit: Added test code as per request
package test;
import java.io.*;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by djb on 2015/06/03.
*/
public class ThreadTest {
public ThreadTest() {
}
static long rand = 10000;
public static void main(String args[])
{
ExecutorService executor = Executors.newFixedThreadPool(5);
File f = new File("C:\\code\\ThreadTest\\text.csv");
try {
Runnable keyPressThread = new ThreadTest.KeyPressThread();
Thread t = new Thread(keyPressThread);
t.start();
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null)
{
try {
final String copy = line;
executor.execute(new Runnable() {
#Override
public void run() {
try {
System.out.println(rand);
Thread.sleep(rand);
System.out.println(copy);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
} catch (Exception e)
{
e.printStackTrace();
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
public static class KeyPressThread implements Runnable {
Scanner inputReader = new Scanner(System.in);
//Method that gets called when the object is instantiated
public KeyPressThread() {
}
public void run() {
String input = inputReader.next();
if (input.equals("["))
{
rand+=100;
System.out.println("Pressed [");
}
if (input.equals("]"))
{
rand-=100;
System.out.println("Pressed ]");
}
}
}
}
Your KeyPressThread is only testing once:
This will make it watch constantly.
public void run()
{
while(true)
{
if (inputReader.hasNext())
{
String input = inputReader.next();
if (input.equals("["))
{
rand+=100;
System.out.println("Pressed [");
}
if (input.equals("]"))
{
rand-=100;
System.out.println("Pressed ]");
}
if (input.equalsIgnoreCase("Q"))
{
break; // stop KeyPressThread
}
}
}
}
System.in is line buffered, by default. This means that no input is actually passed to the program until you press ENTER.
I am embeding Groovy runtime in my code and I would like to have the ability to interrupt it. I don't have control of the scripts that are going to run. I read about groovy.transform.ThreadInterrupt to handle thread interruptions but for some reason this code below isn't working as intended. It's actually waiting 10000 ms instead of the 1000 where it should get interrupted.
Any ideas? Thank you.
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.transform.ThreadInterrupt;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
public class GroovyTest extends Thread {
private Binding binding;
private GroovyShell shell;
public GroovyTest() {
CompilerConfiguration compilerConfig = new CompilerConfiguration();
compilerConfig.addCompilationCustomizers(
new ASTTransformationCustomizer(ThreadInterrupt.class));
binding = new Binding();
shell = new GroovyShell(this.getClass().getClassLoader(), binding, compilerConfig);
}
#Override
public void run() {
System.out.println("Started");
shell.run("for(int i = 0; i < 10; i++) {sleep(1000)}", "test", new String[] {});
System.out.println("Finished");
}
public static void main(String args[]) throws InterruptedException {
GroovyTest test = new GroovyTest();
test.start();
System.out.println("Sleeping: " + System.currentTimeMillis());
Thread.sleep(1000);
System.out.println("Interrupting: " + System.currentTimeMillis());
test.interrupt();
test.join();
System.out.println("Interrupted?: " + System.currentTimeMillis());
}
}
Answering my own question.
Groovy's static method sleep doesn't interrupt even if you try to if there isn't a closure.
Pretty weird default if you ask me.
Recomended way is to call Thread.sleep(ms)
private static void sleepImpl(long millis, Closure closure) {
long start = System.currentTimeMillis();
long rest = millis;
long current;
while (rest > 0) {
try {
Thread.sleep(rest);
rest = 0;
} catch (InterruptedException e) {
if (closure != null) {
if (DefaultTypeTransformation.castToBoolean(closure.call(e))) {
return;
}
}
current = System.currentTimeMillis(); // compensate for closure's time
rest = millis + start - current;
}
}
}