Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6322549
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T16:21:12+00:00 2026-05-24T16:21:12+00:00

I’m using this exercise as a pedagogical tool to help me burn in some

  • 0

I’m using this exercise as a pedagogical tool to help me burn in some Java GUI programming concepts. What I’m looking for is a general understanding, rather than a detailed solution to one specific problem. I expect that coding this “right” will teach me a lot about how to approach future multi-threaded problems. If this is too general for this forum, possibly it belongs in Programmers?

I’m simulating a card reader. It has a GUI, allowing us to load cards into the hopper and press Start and so forth, but its main “client” is the CPU, running on a separate thread and requesting cards.

The card reader maintains a single buffer. If a card request comes in and the buffer is empty, the card reader must read a card from the hopper (which takes 1/4 of a second, this being 1962). After the card has been read into the buffer, the card reader sends the buffer to the CPU, and immediately initiates another buffer-loading operation, in advance of the next request.

If not only the buffer is empty but there are no cards in the hopper, then we must wait until the operator has placed a deck in the hopper and pressed Start (which always initiates a buffer-load operation).

In my implementation, card requests are sent to the card reader in the form of invokeLater() Runnables being queued on the EDT. At myRunnable.run() time, either a buffer will be available (in which case we can send it to the CPU and kick off another buffer-load operation), or the buffer will be empty. What if it’s empty?

Two possibilities: (a) there’s already a buffer-load operation in flight, or (b) the card hopper is empty (or hasn’t been started). In either case, it’s not acceptable to keep the EDT waiting. The work (and the waiting) must be done on a background thread.

For the sake of simplicity, I tried spawning a SwingWorker in response to every card request, regardless of the status of the buffer. The pseudocode was:

SwingWorker worker = new SwingWorker<Void, Void>() {
    public Void doInBackground() throws Exception {
        if (buffer.isEmpty()) {
            /*
             * fill() takes 1/4 second (simulated by Thread.sleep)
             * or possibly minutes if we need to have another 
             * card deck mounted by operator.
             */
            buffer.fill();
        }
        Card card = buffer.get(); // empties buffer
        /*
         * Send card to CPU
         */
        CPU.sendMessage(card); // <== (A) put card in msg queue
        /* 
         * Possible race window here!!
         */
        buffer.fill(); //         <== (B) pre-fetch next card
        return null;
    }
};
worker.execute();

This produced some odd timing effects – due, I suspect, to a buffer.fill() race that could occur as follows: if, between (A) and (B), the CPU received the card, sent a request for another one, and had another SwingWorker thread spawned on its behalf, then there might be two threads simultaneously trying to fill the buffer. [Removing the pre-fetch call at (B) solved that.]

So I think spawning a SwingWorker thread for every read is wrong. The buffering and sending of cards must be serialized in a single thread. That thread must attempt to pre-fetch a buffer, and must be able to wait and resume if we run out of cards and have to wait for more to be placed in the hopper. I suspect that SwingWorker has what is required to be a long-running background thread to handle this, but I’m not quite there yet.

Assuming a SwingWorker thread is the way to go, how might I implement this, eliminating delay on the EDT, allowing the thread to block awaiting a hopper refill, and handling the uncertainty of whether buffer-filling completes before or after another card request arrives?


EDIT: I got an answer from another thread and will recap it here:

Instead of using a SwingWorker thread, it was recommended I create an ExecutorService newSingleThreadExecutor() once, at the beginning, and have the GUI enqueue lengthy methods on it using execute(Runnable foo), as follows (this code runs in the EDT):

private ExecutorService executorService;
::
/*
 * In constructor: create the thread
 */
executorService = Executors.newSingleThreadExecutor();
::
/*
 * When EDT receives a request for a card it calls readCard(),
 * which queues the work out to the *single* thread.
 */
public void readCard() throws Exception {
    executorService.execute(new Runnable() {
        public void run() {
            if (buffer.isEmpty()) {
                /*
                 * fill() takes 1/4 second (simulated by Thread.sleep)
                 * or possibly minutes if we need to have another 
                 * card deck mounted by operator.
                 */
                buffer.fill();
            }
            Card card = buffer.get(); // empties buffer
            /*
             * Send card to CPU
             */
            CPU.sendMessage(card); // <== (A) put card in msg queue
            /* 
             * No race!  Next request will run on same thread, after us.
             */
            buffer.fill(); //         <== (B) pre-fetch next card
            return;
        }
    });
}

The main difference between this and SwingWorker is that this ensures there’s only one worker thread.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T16:21:13+00:00Added an answer on May 24, 2026 at 4:21 pm

    There was one thing missing from the “answer” I had appended to the original question:

    I was handing off the time-consuming work (nothing more than a Thread.sleep() for pedagogical purposes) to a background thread, via a Single Thread Executor. A problem arose, however, because the background thread was “reading a card” by poll()ing the List that was serving as the data model for a Swing component, and raising lots of AWT array index out of range exceptions. After several futile attempts to synchronize access to the List by both the EDT and my background thread, I punted, and wrapped the commands to poll() the List and update the GUI in a small Runnable(), and used invokeAndWait() to cause them to run on the EDT while my background task waited.

    Here’s my revised solution:

    private ExecutorService executorService;
     :
    executorService = Executors.newSingleThreadExecutor();
     :
    /*
     * When EDT receives a request for a card it calls readCard(),
     * which queues the work to the *single* thread.
     */
    public void readCard() throws Exception {
        executorService.execute(new Runnable() {
            public void run() {
                if (buffer.isEmpty()) {
                    /*
                     * fill() takes 1/4 second (simulated by Thread.sleep)
                     */
                    buffer.fill();
                }
                Card card = buffer.get(); // empties buffer
                /*
                 * Send card to CPU
                 */
                CPU.sendMessage(card); // <== (A) put card in msg queue
                /* 
                 * No race!  Next request will run on same thread, after us.
                 */
                buffer.fill(); //         <== (B) pre-fetch next card
                return;
            }
        });
    }
    
    /*
     * IMPORTANT MODIFICATION HERE - - -
     *
     * buffer fill() method has to remove item from the list that is the
     * model behind a JList - only safe way is to do that on EDT!
     */
    private void fill() {
        SwingUtilities.invokeAndWait(new Runnable() {
            /*
             * Running here on the EDT
             */
            public void run() {
                /*
                 * Hopper not empty, so we will be able to read a card.
                 */
                buffer = readHopper.pollLast();  // read next card from current deck
                fireIntervalRemoved(this, readHopper.size(), readHopper.size()); 
                gui.viewBottomOfHopper(); // scroll read hopper view correctly
            }
        });
        // back to my worker thread, to do 1/4 sec. of heavy number crunching ;)
        // while leaving the GUI responsive 
        Thread.sleep(250);
         :
        etc.
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have thousands of HTML files to process using Groovy/Java and I need to
I have some data like this: 1 2 3 4 5 9 2 6
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
That's pretty much it. I'm using Nokogiri to scrape a web page what has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I have a jquery bug and I've been looking for hours now, I can't
this is what i have right now Drawing an RSS feed into the php,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.