I don't know how to do this, what i am trying to do is running a for loop and still can do other things like reading input from user,change files contents, etc...(you get the idea) while the loop is running, is there any way to do it?
Btw i am using java
You can create a new Thread for the task you want to do separately while the loop is running.
Thread t = new Thread(() -> {
//your code here
});
t.start();
You can do that using threads in java. Java don't support callbacks but with threads you can run multiple process at the same time. You can read more about threads in the java doc.or any java tutorial. The while loop should run on a separate thread while other things you want to do should run on another thread.
You can Do it like this:
// the Thread class
class ThreadDemo extends Thread
{
public void run()
{
try
{
//Loop code
for(int counter = 0; counter < x ;counter++){
}
}
catch (Exception e)
{
// Throwing an exception
System.out.println ("Exception is caught");
}
}
}
// Main Class
public class Multithread
{
public static void main(String[] args)
{
ThreadDemo object = new ThreadDemo();
object.start();
}
}
More on Threads
Related
I am fork a new thread on my service's #Postconstruct method, and in the new thread, a infinite loop is running.
My test is just invoke the service using spring mvc test:
ResultActions result = this.mockMvc.perform(post("/test").with(httpBasic(user, pwd)).contentType("application/json").content(test))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
And the test just hangs there, waiting for the infinite loop thread to stop. but when the service is started normally, the test is fine. Any idea why? And how to fix it.
here is the code in my service java:
#Postconstruct
private void init() {
invoke();
}
private void invoke() {
Runnable task = () -> {
while(true) { ... }
}
Thread t;
for(int i=0; i<3; i++) {
t = new Thread(task);
t.setName("test-" + i);
t.start();
}
}
Suggestion: step back from using "bare metal" Threads. There are nice abstraction concepts, like ExecutorService and things like Futures and Promises.
The point is: one can use dependency injection to provide such an ExecutorService to the production code; and then you can define your own service ... that does everything on the same thread.
Meaning: avoid unit tests that deal with multiple threads - as that often leads to additional waiting, or "flakiness" as you never now exactly how long your test will be running.
Take a look at this example (with a debugger)
Notice that the main will not be exited until all the threads are done.
You can easily do this with putting a breakpoint on a while (run) and change the value of run slowly. Once you turn off all 3 threads, then your main thread will exit.
class Test {
public static void main(String[] args) {
Runnable task = () -> {
boolean run = true;
while (run) {
System.out.println("running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Thread t = new Thread(task);
t.setName("test-" + i);
t.start();
threads.add(t);
}
}
}
Another way to do it is using join, which will explicitly wait for the threads to finish before the program can complete.
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
While there are any active threads running the program will not finish.
class myRunnable implements Runnable {
public void run() {
// TODO Auto-generated method stub
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
}
}
}
Result in the console:
main
main
main
main
...
main
main
main
main
I can't find any "run" word, this means the run method didn't run. Can somebody explain that for me. Thank you.
PS: when i<10, i<100, i<1000, i<10000, I can find the "run" word, but when i<100000 then I can't find the "run" word, that's just weird
Run has been printed out. But your console-buffer is not large enougth.
Change the Console-configuration to unlimited buffer.
First of all, Yes, Your code actually prints "run".
Just make this little change below and You´ll see it.
A more rigorous test, If You can see it in a different way, is to send the strings to a text file instead of the console. You will certanly find the word "run".
class myRunnable implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Your implementation runs just fine. You just don't see your run message because there hasn't been any thread switch just yet.
The problem is that the action on which you examine the threads is too short. You can insert a Thread.sleep(2000); for example to check it out.
I find this wired that you can't find a run in your output, the thing is that you should understand how the java thread mechanism works, the main thread will not wait for the child thread to complete their work, unless you make it specific, thus whether or not the child complete before the main thread complete (and exit) is not expectancy.
if you do want the main thread to wait for the child thread to complete, you can make it specific by:
t.start();
t.join();
You should have to catch some exception to make this work.
But I think it should be high ratio that you should see a run printed in your original code. because it seems the main thread is more time consuming.
regardless of this, there is nothing to blame if your jvm behave like this. the thread executing order is not insured by the standard anyway.
Simply add a delay of one second within the loop as displayed below:
class myRunnable implements Runnable {
public void run() {
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have this code below, that evaluates if three threads are done, and if yes, it continues with the code. The problem is that when I include some sort of print statement before the if statement, it works as usual. However, when I don't include the print, it continues forever. Here it is:
while (!are_we_done) {
System.out.println(are_we_done);
if (thread_arr[0].are_we_done==true && thread_arr[1].are_we_done==true && thread_arr[2].are_we_done==true) {
are_we_done=true;
}
}
Any clue as to what's going on?
Thanks in advance for any help/advice.
The problem was that I had to specify the are_we_done variable in the thread class as volatile.
Your work with threads is awesome - google for 'busy waiting'.
in main thread introduce 'latch = new CountDownLatch(<number of threads>)' variable
pass it into all your threads
on finish of the thread call 'latch.countDown()'
in main thread wait for all spawned threads complete with 'latch.await(...)'
Example:
public static void main(String... args) throws Exception {
Thread[] threads = new Thread[3];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new YourRunnable(latch));
threads[i].start();
}
while (!latch.await(1000)) {
System.out.println("Not complete yet");
}
System.out.println("Complete!");
}
public class YourRunndable implements Runnable {
... // fields + constructor
public void run() {
try {
... // do your staff
} finally {
latch.countDown();
}
}
}
This question already has answers here:
Odd even number printing using thread
(13 answers)
Closed 8 years ago.
I am learning Java but have trouble with synchronized. i want print list of numbers from many Java threads and have each thread go in order.I get problem when using synchronized because i not much understand. Can help understand?
I want output to see this but sometimes threads in wrong order.i want:
1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1
My broken codes:
public class ManyThreadsAdd {
public static int index = 0;
public static void main(String[] args) {
ManyThreadsAdd myClass = new ManyThreadsAdd();
Thread thread1 = new Thread(myClass.new RunnableClass());
Thread thread2 = new Thread(myClass.new RunnableClass());
thread1.start();
thread2.start();
}
class RunnableClass implements Runnable {
public synchronized void run() {
while (index < 49) {
try {
Thread.sleep(100);
System.out.println(index+"-" +Thread.currentThread());
index = index + 1;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
It depends on what you want to do.
A simple way to alternate the order of the print is to synchronize on the same object, in this case you can use the index or any other object.
public class ManyThreadsAdd {
public static AtomicInteger index = new AtomicInteger(0);
public static void main(String[] args) {
ManyThreadsAdd myClass = new ManyThreadsAdd();
Thread thread1 = new Thread(myClass.new RunnableClass());
Thread thread2 = new Thread(myClass.new RunnableClass());
thread1.start();
thread2.start();
}
class RunnableClass implements Runnable {
public void run(){
synchronized(index){
while(index.get() < 49){
try {
Thread.sleep(100);
System.out.println(index.get()+"-" +Thread.currentThread());
index.incrementAndGet();
index.notify();
index.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
Firstly, multithreading by nature is asynchronous, you cannot specify the order in which these threads get executed. If you want output like below, use a loop:
1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1
Secondly, you gain nothing by adding the synchronized keyword in public synchronized void run(). This just means that at any time, only one thread at a time can call that method. As you are constructing new classes for each thread, this is meaningless.
Thirdly, if you did need to synchronise between your threads, use a queue to which you add tasks, and which your threads read one at a time.
I have this code(FULL SOURCE CODE) :-
class thread implements Runnable {
int i=0;
Thread t;
public void main(){
t= new Thread(this); //edited
for(i=0;i<=5;i++){
System.out.println(i);
}
}
public void run(){
try{
Thread.sleep(1000); //EDITED EARLIER, was: t.sleep(1000);
}
catch(InterruptedException e){
}
}
}
The thread is supposed to sleep for 1 second. But, the thread does not sleep at all. Where am I going wrong. Any help will be appreciated.
EDIT
I get the following error now ->
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:682)
at thread.main(thread.java:7)
The fundamental issue here is that you never start the thread. Your program's main is called on the default thread, you create an instance, and then do nothing with it.
If you want to start your thread, call t.start() (once). That will start your thread, which will run alongside the default thread the JVM created when running your program. Other than that both threads are running at the same time, they don't interact in your program, so you'll still see the numbers get printed out right away. Depending on what you're trying to do, you may want to move your loop from main to run.
(And yes, sleep is a static method which makes the current thread sleep. In Java, it's syntactically valid to call a static method through an instance reference, but it's a bad idea.)
So for instance, here's your class with minimal mods (note: your environment seems to create an instance and call the instance-specific main below, which is non-standard,but I left it alone as it seems to be what your environment does):
class ThreadExample implements Runnable
{
public void main(){
Thread t= new Thread(this);
t.start();
}
public void run(){
int i;
try{
Thread.sleep(1000);
for(i=0;i<=5;i++){
System.out.println(i);
}
}
catch(InterruptedException e){
}
}
}
Changes:
Use standard Java naming conventions for the class.
Make t a local variable in main.
Actually start the thread in main.
Move loop from main to run, after the sleep call.
Make i a local variable in run.
Call sleep via Thread rather than this.
Here's a more normal example with a static main:
class ThreadExample implements Runnable
{
public static void main(String[] args) {
Thread t = new Thread(new ThreadExample());
t.start();
}
public void run(){
int i;
try{
Thread.sleep(1000);
for(i=0;i<=5;i++){
System.out.println(i);
}
}
catch(InterruptedException e){
}
}
}
Live example with debug output
The sleep method in Thread is static, so it should be called Thread.sleep() and it actually makes the currently executing thread to sleep, not a specific thread instance that you call the method on.
Your code should look more like this. It has been a while since I've worked with threads so there might be minor errors people should feel free to edit.
class myThread implements Runnable
{
public void main(){
MyThread t= new MyThread();
t.start();
t.join();
}
public void run(){
try{
for(i=0;i<=5;i++){
System.out.println(i);
Thread.sleep(1000);
}
}
catch(InterruptedException e){
}
}
}