0

I want to use a Thread that sorts a list with my method quicksort.

Unfortunately I dont know how to do that.

   ------------------
blabla other Methodes that quicksort/ sort needs....

   ------------------




public static void sort(int[] list) {
        quickSort(list, 0, (list.length-1)); // <--- I want use this in a Thread

    }  


 public static void main (String[] args) {
        int[] newList = {5, 7, 23, 87, 11, 0, 5, 33, 30,512, 125, 215 ,7, 234, 152, 125};
        for(int i: newList) {
            System.out.print(i + " ");
        }

        System.out.println();
        sort(newList);                // <--- OR I want use this in a Thread

My Problem is that I dont know how to use a Method with Parameters in a Thread.

Does someone know a good Tutorial that explains me how to do that?

What better implement Runnable or extends Thread?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Gaga1231
  • 5
  • 2

3 Answers3

1

You can really only do this by using fields to store the data.

You can easily accomplish this with a constructor;

public Worker extends Thread
{
   Object data1, data2, //...
   public Worker(Object data0, Object data1, ...)
   {
    //set the fields
   }

   public void run()
   {
      //do stuff using the fields we set
   }
}

Now to pass the thread the correct data; new Worker(data1, data2, ...).start();

But thread creation is very expensive, and you want to make each thread do as much as possible. For example, if you needed to run this method a significant number of times, then the Executor framework, or having your threads pull data from collections, would be more appropriate.

KookieMonster
  • 505
  • 2
  • 6
  • 2
    No, a mutable `static` variable isn't a more appropriate solution. Inject the instance to the constructor. Actually, never mind that - you're reinventing executors here. Just use the executor framework. – Andy Turner Apr 25 '16 at 13:12
  • Good point about the executors. I don't use Java enough, it skipped my mind. I will edit that in. Re mutable statics, is this just a problem with accidentally replacing the collection/reference, or is there something else that I should be aware of? – KookieMonster Apr 25 '16 at 13:23
  • It is simply the problem with all mutable global state: you don't know what state anybody else left it in, and you don't know what they will do while you are using it. – Andy Turner Apr 25 '16 at 13:24
  • Ah, as in, add a final modifier or pass the reference directly. I see what you mean. Would I be correct in saying that this wouldn't be an issue if you didn't explicitly fiddle with the state at any point? – KookieMonster Apr 25 '16 at 13:27
  • "add a final modifier" No. That's still static mutable state, you just can't replace the `ConcurrentLinkedQueue` with a different instance. It doesn't stop you calling `data.put()` or `data.pop()`, for instance. – Andy Turner Apr 25 '16 at 13:38
  • Ah, that's why I didn't get what you were saying. I used ConcurrentLinkedQueue specifically because this issue is not relevant - implementations of this queue already guarantee thread safety on all invocations of `poll()` and `add(E)` – KookieMonster Apr 25 '16 at 13:46
  • No, you are still missing my point. If you make the variable static, you can't have two separate queues of tasks to be run by two separate pools of threads. – Andy Turner Apr 25 '16 at 13:49
  • You don't need two separate queues. Java's Concurrent (and Blocking) collections can be accessed simultaneously by multiple threads, so you would only need one central collection. – KookieMonster Apr 25 '16 at 13:52
  • You are really missing the point. You have some tasks; I have some tasks. I have submitted my tasks to the queue. You come along and are able to clear my tasks out of the queue; or you're able to run your tasks on my threads; or an exception in one of your runnables kills my thread, so my tasks don't get run. This is all entirely avoidable if we have had to provide our own queues (an exception in your tasks might then kill *your* threads, but that's your problem, not mine). – Andy Turner Apr 25 '16 at 13:59
  • Ah, I did miss the point a little bit. I think we just have different expectations in regards to robustness. I just assume that exceptions are handled, collections aren't being arbitrarily repurposed, etc. You think that this assumption isn't safe enough. I don't think we can come to an agreement on this. – KookieMonster Apr 25 '16 at 14:36
1
    final int[] newList = {5, 7, 23, 87, 11, 0, 5, 33, 30,512, 125, 215 ,7, 234, 152, 125};

    System.out.println();

    thread t = new Thread () {
        public void run () {
            sort(newList);     
        }
    };
    t.start();

Note that 'newList' has to be final.

David Zimmerman
  • 335
  • 4
  • 7
0

You've got one basic approach and a couple implementations. The basic approach is to extend the base class and pass in your parameter to the constructor. Store that parameter in a final field, and then access it from your run() method. Example:

public class QuickSort extends Thread {
    final int[] entries;

    public QuickSort(int[] list) {
        entries = list;
    }

    public void run() {
        // do your quick sort.
        // the final int[] entries just keeps the list from being
        // replaced at run time, the entries themselves are not frozen.
    }
}

To use the thread, you would execute it like this:

QuikSort qs = new QuickSort(myList);
qs.start();

// When you need to wait for the sort to be done:
// Don't try to use the list before hand because it's
// state will be undefined.
qs.join();

The problem with this is we are burning a whole thread for a relatively short time. Threads are expensive operating system resources and they can take a while to finish cleaning up. It's better to reuse threads. Thankfully, the Executor system was created to make this easier (I remember creating one in a framework a long time ago before this was available).

The end strategy is effectively the same, except your Executor is in charge of spinning up or reusing threads for your short term asynchronous work.

Berin Loritsch
  • 11,400
  • 4
  • 30
  • 57