Nicolás Videla
Nicolás Videla

Reputation: 44

Simple java threading test program not working

I'm trying to make an extremely simple "calculator" in java to understand threading, since it's the implementation I've found for a concurrent programming scenario in Java.

The way it was presented in my class was the following:

cobegin
  a = a + 10
  b = b - 3
coend
c = b - a
w = c + 1

I did some research and I tried to implement it this way in java, but it's returning 0 to all values.

Main class public class Threading {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int a = 0;
        int b = 0;
        Threader t1 = new Threader(a, '+', 10); 
        System.out.println("a" + a);
        Threader t2 = new Threader(b, '-', 3);
        System.out.println("b" + b);
        t1.start();
        a = t1.res;
        System.out.println("a>>thread" + a);
        t2.start();
        b = t2.res;
        System.out.println("b>>thread" +b);
        int c = b - a;
        System.out.println("c" + c);
        int w = c + 1;
        System.out.println("w" +c);

    }

Class supposed to do the threading

public class Threader extends Thread {

    private char op;
    private int a;
    private int b;
    public int res;

    public Threader(int _a, char _op, int _b) {
        a = _a;
        b = _b;
        op = _op;
    }

    @Override
    public void run() {
        Operator ope = new Operator();
        res = ope.operar(a, op, b);
    }
}

The operator class

public class Operator {

    public int operar(int a, char op, int b) {
        if (op == '+') {
            return sum(a, b);
        }
        if (op == '-') {
            return substr(a, b);
        }
        if (op == '*') {
            return mult(a, b);
        }
        if (op == '/') {
            return div(a, b);
        } else {
            return Integer.MAX_VALUE;
        }
    }

    public int sum(int a, int b) {
        return a + b;
    }

    public int substr(int a, int b) {
        return a - b;
    }

    public int mult(int a, int b) {
        return a * b;
    }

    public int div(int a, int b) {
        if (b > 0) {
            return a / b;
        } else {
            return Integer.MAX_VALUE;
        }
    }
}

What am I missing? Is there a better approach to the problem in Java?

Upvotes: 0

Views: 95

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27115

IMO, this is a bad example of how to use threads.

The first question I always ask about any thread is, "What does it wait for?" That's pretty much what defines any thread. A server thread waits for incoming connections from clients, A client thread waits for a particular client to send the next command, A GUI thread waits for keyboard and mouse input, a worker thread waits for tasks to perform, etc.

Your threads don't wait for anything. (And there's the bug in your program, by the way: Your main thread does not even wait for the workers to compute a result.)

Your program is a degenerate example of one unusual exception to the rule: It's a program that performs a single computation. In that case, it can make sense to create worker threads that don't have to wait because each one knows its task from the moment it is created. The program creates the threads, the threads perform their tasks, the main thread waits for the individual results, combines them, and then the program is done.

But that is an unusual case.

More typically, a compute-intensive program will use a pool of worker threads to perform many computations. And, those worker threads, when they are not actively computing wait for the next piece of work. And, that's what defines them.

If you want to learn how to think about threads, think about what they wait for.

IMO.

Upvotes: 2

Reut Sharabani
Reut Sharabani

Reputation: 31339

Make sure to join your threads to know they've finished:

t1.start();
t1.join();

This obviously misses the point of threading so make sure you join when you need the result.

More notes:

You don't need to extend Thread. You are not making special threads, you are making special tasks. The default threads are more than enough to run them.

Use this class:

public class RunnableTask implements Runnable {

    // consider using a getter
    public int res;
    private int a;
    private char c;
    private int i;

    public RunnableTask(int a, char c, int i) {
        this.a = a;
        this.c = c;
        this.i = i;
    }

    @Override
    public void run() {
        Operator ope = new Operator();
        this.res = ope.operar(a, this.c, this.i);
    }

}

Now use the threads like this:

public class Main {
    /**
     * @param args
     *            the command line arguments
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        int a = 0;
        int b = 0;
        RunnableTask task1 = new RunnableTask(a, '+', 10);
        RunnableTask task2 = new RunnableTask(b, '-', 3);
        Thread t1 = new Thread(task1);
        System.out.println("a" + a);
        Thread t2 = new Thread(task2);
        System.out.println("b" + b);
        t1.start();
        t1.join();
        a = task1.res;
        System.out.println("a>>thread" + a);
        t2.start();
        t2.join();
        b = task2.res;
        System.out.println("b>>thread" + b);
        int c = b - a;
        System.out.println("c" + c);
        int w = c + 1;
        System.out.println("w" + c);

    }
}

Upvotes: 2

Related Questions