spotTop
spotTop

Reputation: 87

Threading is not working correctly?

Doing a threading problem and I am not sure if this is how its supposed to be or if I coded incorrectly. From what I understand, threading should have multiple methods going at the same time and because of this they should be intertwined. My code is supposed to take a single char and repeat 1000 times but instead of having different variations of the two letters it goes "a" a thousand times, then "b" a thousand times. What is my issue?

Main Method

import java.util.*;
public class MainThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner answer = new Scanner(System.in);

        System.out.println("Give me a single character: ");
        char h = answer.next().charAt(0);
        System.out.println("Give me another single character: ");
        char a = answer.next().charAt(0);   

        MyThread t1 = new MyThread(h);
        MyThread t2 = new MyThread(a);

        t1.start(h);
        t2.start(a);        

        answer.close(); 
    }
}

my Threading class

import java.util.*;
public class MyThread extends Thread{

    Scanner answer = new Scanner(System.in);

    public MyThread(char x) {
        // TODO Auto-generated constructor stub
    }


    public void Stored(char x){
        System.out.println("Type a single letter here: ");      
    }


    //modified run method 
    public void start(char x){

        for(int i = 0; i < 1000; i++){
            System.out.print(x);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {              
                e.printStackTrace();
            }
            Thread.yield();
        }
    }   
}

Upvotes: 3

Views: 6209

Answers (4)

user85421
user85421

Reputation: 29730

The error was already explained: the start method is being overridden instead of the run method. Anyway it is not recommended to extend the Thread class since you are not wanting to extend its functionality.

You just want to use a Thread, so a better approach (IMO) is to provide a Runnable to the Thread:

    public static void main(String[] args) {
        // ...
        Thread t1 = new Thread(new MyRunnable(h));
        t1.start();
    }

The Runnable (use a better Name in production code):

public class MyRunnable implements Runnable {

    private final char ch;

    public MyRunnable(char theChar) {
        ch = theChar;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            ...
        }
    }

This could be improved using with Lambda, but is not the point here

More: "implements Runnable" vs. "extends Thread"

Upvotes: 0

Vasu
Vasu

Reputation: 22452

What you have done is NOT multithreading, rather you have called the start method sequentially, i.e., in order to run the multiple threads parallelly, you need to override the run() method in your MyThread class.

The important point is that run() method will be called by JVM automatically when you start the Thread, and the code inside run() will be executed in parallel with the main/other threads, so override run() inside MyThread class as shown below:

class MyThread extends Thread {

    private char x;

    public MyThread(char x) {
        this.x= x;
    }

    // Add run() method
    public void run() {

        for (int i = 0; i < 10; i++) {
            System.out.print(x);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
            Thread.yield();
        }
    }
}

MainThread class:

public class MainThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner answer = new Scanner(System.in);

        System.out.println("Give me a single character: ");
        char h = answer.next().charAt(0);
        System.out.println("Give me another single character: ");
        char a = answer.next().charAt(0);   

        MyThread t1 = new MyThread(h);
        MyThread t2 = new MyThread(a);

        t1.start();//this calls run() of t1 automatically
        t2.start();//this calls run() of t2 automatically        

        answer.close(); 
    }
}

I suggest you have a look here for basic understanding on how to create and start the Thread and how multi-threading works.

Upvotes: 2

ldz
ldz

Reputation: 2215

In order to let the threads run in parallel, the run method needs to be implemented instead of start.

See the JavaDoc for Thread.start():

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).

Upvotes: 1

Christoph Bimminger
Christoph Bimminger

Reputation: 1018

First of all, it's not guaranteed that your described behavior will never occur, even when you implement a correct multithreading. But, it shouldn't be repeatable ;)

The solution is: don't override the start() but the run() method. The thread constructor should take the argument, the start() is called (and no new start method with an argument!) from the main, and the run() implements the job that is executed parallel. Therefore, you can access the thread's field which you set in your thread constructor.

Upvotes: 0

Related Questions