3

Long story short; I've written a program that contains an infinite loop, in which a function is run continuously, and must run as quickly as is possible.

However, whilst this function completes in a microsecond time scale, I need to spawn another thread that will take considerably longer to run, but it must not affect the previous thread.

Hopefully this example will help explain things:

while (updateGUI == true) { //So, forever until terminated

        final String tableContents = parser.readTable(location, header);
        if (tableContents.length() == 0) {//No table there, nothing to do
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                    //updateTable updates a JTable 
                    updateTable(tableContents, TableModel);
                    TableColumnModel tcm = guiTable.getColumnModel();
                }
            });
        }
     ***New thread is needed here!
    }

So what I need is for the readTable function to run an infinite number of times, however I then need to start a second thread that will also run an infinite number of times, however it will take milliseconds/seconds to complete, as it has to perform some file I/O and can take a bit of time to complete.

I've played around with extending the Thread class, and using the Executors.newCacheThreadPool to try spawning a new thread. However, anything I do causes the readTable function to slow down, and results in the table not being updated correctly, as it cannot read the data fast enough.

Chances are I need to redesign the way this loop runs, or possible just start two new threads and put the infinite looping within them instead.

The reason for it being designed this way was due to the fact that once the updateTable function runs, it returns a string that is used to update a JTable, which (as far as I know), must be done on Java's Main Dispatch Thread, as that is where the GUI's table was created.

If anyone has any suggestions I'd greatly appreciate them.

Thanks

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Tony
  • 3,587
  • 8
  • 44
  • 77

4 Answers4

3

As you are updating a JTable, SwingWorker will be convenient. In this case, one worker can coexist with another, as suggested here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks trashgod. I think swingworkers are the way to go. I'll go back to my code and rework it. Thanks for the input. – Tony Oct 30 '13 at 10:55
3

You have to be very careful to avoid overloading your machine. You long running task need to be made independent of you thread which must be fast. You also need to put a cap on how many of these are running at once. I would put a cap of one to start with.

Also you screen can only update so fast, and you can only see the screen updating so fast. I would limit the number of updates per second to 20 to start with.

BTW Setting the priority only helps if your machine is overloaded. Your goal should be to ensure it is not overloaded in the first place and then the priority shouldn't matter.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Thanks Peter. Good point. I think I need to go back and find a better place for handling the updates to the GUI, and also the spawning of the threads. – Tony Oct 30 '13 at 10:37
  • Do you really need to spawn threads? Can you just have one thread to do the work they are doing? – Peter Lawrey Oct 30 '13 at 10:44
  • 2
    For reference, `SwingWorker` [limits](http://stackoverflow.com/a/11838349/230513) GUI updates to 33Hz. – trashgod Oct 30 '13 at 10:46
  • @trashgod good point. A cinema movie flickers at 42 Hz (every ~27 ms) and you can't see that. – Peter Lawrey Oct 30 '13 at 10:55
  • 1
    @Peter Lawrey FlameWar, this is wrong idea to compare LCD (standard) and Cinema 24_times per sec, don't compare too slow single pixels repainting with replacing whole area, this is possible with proffesional plasma displays (syncronous) or CRT (asynchronous, because pixels are repainted from top-left to right-bottom, then there is small delay) – mKorbel Oct 30 '13 at 12:16
  • @mKorbel Doing a bit of research, I found this interesting. http://www.100fps.com/how_many_frames_can_humans_see.htm It suggests that it depends on what you are talking about as to what is noticeable. – Peter Lawrey Oct 30 '13 at 14:58
  • @Peter Lawrey agreed, this is good point, because this theory is very different to real products in the shop, – mKorbel Oct 30 '13 at 16:09
2

It's very hard to guess what's going on here, but you said "results in the table not being updated correctly, as it cannot read the data fast enough". If you really mean the correctness of the code is affected by the timing not being fast enough, then your code is not thread safe and you need to use proper synchronization.

Correctness must not depend on timing, as timing of thread execution is not deterministic on standard JVMs.

Also, do not fiddle with thread priorities. Unless you are a concurrency guru trying to do something very unusual, you don't need to do this and it may make things confusing and/or break.

Enno Shioji
  • 26,542
  • 13
  • 70
  • 109
  • Thanks Enno. Essentially what's happening is the infinite loop reads from a memory mapped file that another process generates. That file changes continuously as such must be parsed as quickly as possible as it's constantly being updated. – Tony Oct 30 '13 at 10:31
  • You may be able to use file locks. But something like sockets or named pipes sounds better. Essentially you are getting updates from this process which you don't want to miss, right? – Enno Shioji Oct 30 '13 at 10:38
0

So if you want your "infinite" looping thread to have max priority, why are you setting priority to MAX for EDT insted of you "most precious one"?

               Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                //updateTable updates a JTable 
                updateTable(tableContents, TableModel);
                TableColumnModel tcm = guiTable.getColumnModel();

In this piece of code current thread will be and EDT, or EDT spawned one. Why not moving that line before intering whileloop?

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • That Max priority line was added during testing, as I tried spawning another thread afterwards. It can be removed in fairness as the other thread no longer exists. – Tony Oct 30 '13 at 10:29