Java Practice Assignment #3 – Assembly Line

by Trevor Page on January 9, 2013

Java Practice Assignment 3

Solution for Assignment 2

First let’s start off with the solution for assignment 2 before we jump into our next assignment.

Click Here to download the source files for assignment 2′s solution

For your viewing pleasure, here’s the video walk-through for assignment 2 as well:

Requirements for Java Practice Assignment 3

In this weeks Java practice assignment, your job is to implement the simulation of an assembly line that will build Cars. Each Car is made up of several components: tires, seats, engine and frame. Each of these components takes a different amount of time to build on their own. Here’s the breakdown on the simulated time each component takes to construct:

  • Tire – 2 seconds
  • Seats – 3 seconds
  • Engine – 7 seconds
  • Frame – 5 seconds

With these times, you must implement the code that will simulate the construction of each of these components individually, then once all the necessary components are built you must put them together to make a car. To build a car, you’ll need 4 tires, 5 seats, 1 engine and 1 frame. Here’s the catch, the assembly line can only and should only be capable of building 3 Components at any given time. You’ll need to implement this in your code.

Once you’ve completed the assignment and all unit tests are passing, try and fiddle with the order of which the Components are assembled on the line. Is there a particular order that provides the fastest building time for a Car?

Download

Click here to download the source files

Remember

This assignment deals with multithreading and the singleton design pattern. Be sure to read up on these two articles before you try to complete the assignment:

Multithreading
Singleton Design Pattern

If you encounter strange issues, just think in terms of the fact that you have multiple threads running at the SAME TIME doing their thing. Most problems can be solved by realizing this, and understanding exactly what’s going on in the code. I would recommend the use of plenty of System.out.println() statements to be used as logging so you can get a picture of what exactly is happening at any given moment.

Hint: if you are struggling to make the very last unit test pass, do some research on the synchronized keyword.

Best of luck and if you are really really stuck, just post a comment below. Also, if you see a question from another reader, and you know the answer, feel free to jump in and contribute :)

Top 7 Tools to Launch Web Apps
Popular Java Tools
Free to Download
Extremely Useful

{ 12 comments… read them below or add one }

ALJI Mohamed January 10, 2013 at 9:39 am

How about the solution of the second assignment ?

Reply

Trevor Page January 10, 2013 at 10:02 am

Silly me, I’ll add that in right now

Reply

Bernd January 12, 2013 at 4:55 am

Thank you for this really great challenge! This one was a *bit* harder…

Here the main problem was not Java, but to determine the thread logic. Which thread sets/resets the flags under which conditions.

My Cars are built within 12 seconds now, which definitely is the minimal time.

But it seems the clocks do not run at the same speed in each thread. All the single component tests fail, because my code is too fast ;-)
For example my Frame is built within 5000 ms according to its own logging, but the unit test calculates 4938 ms and therefore fails.

I can’t wait to see your solution.

Reply

Martin January 13, 2013 at 1:15 pm

Hi Bernd,

There is actually a bug in the test code for test_engine_completion_time and test_frame_completion_time.
In the while (!component.isBuilt()) loop the end = new Date(); line should come after the Thread.sleep(100); line, as you can seen in the test_seat_completion_time and test_tire_completion_time tests.
If you put the end = new Date(); before the Thread.sleep(100); line the recorded end time can be up to 100ms off .

Reply

Trevor Page January 13, 2013 at 10:15 pm

Hey Martin,

Thanks for pointing that out, I’ve updated the source files to reflect these changes.

Bugs bugs bugs

Reply

Bernd January 14, 2013 at 3:44 am

Thank you, Martin! I think I’m blind sometimes.
I have also added a wait for “waitForAssemblyLine ready” before each single test, because they seem to be performed in a random order sometimes.

Lessons learned by now:
1) Always check everything ;-)
2) object.wait() and object.notifyAll() is much faster and more accurate than Tread.sleep()
3) Several threads on the same method in the same object (in my case AssemblyLine.run(), used to build one car) share the same local variables. This is self-evident, but not obvious…

Reply

Steve Brouillard January 17, 2013 at 2:44 pm

Any chance of a video solution like you did on the last one Trevor? I have to admit that I never really got out of the starting blocks on this one … this one had me completely brain-locked. I’m really confused on the whole purpose of the ‘public static void main …’ line of code. Doesn’t this signify the starting point of the program? In this assignment, your solution shows a Main class with this statement in it but it is empty? Are the tests just testing the logic and methods between the different classes and how they function together? I guess I’m still really hung up on the whole purpose of ‘public static void main …’. Is there a starting point and ending point to this particular program or is just a set of relationships between the different classes? What am I failing to grasp?
After looking at part of the solution, I’m also having a hard time wrapping my brain around why the statement: private static final AssemblyLine INSTANCE = new AssemblyLine();
guarantees a singleton. I realize this is supposed to be a constant but the right hand side of the expression (INSTANCE = new(AssemblyLine()) throws doubt in my mind why this would be so. Can you elaborate?

Reply

Trevor Page January 17, 2013 at 4:22 pm

Hey Steve,

I’m thinking that the video solution for this one will be part of javavideotutorials.net only. So just hang tight for now, I’ll be recording it in the near future.

Also, I goofed with the Main class, I had originally started the solution with a public static void main and then never used it. I just removed that entire Class from my solution (and you can delete it too).

A public static void main(String[] args) method is used to mark the beginning of a program when you’re running it like an executable file. So you are absolutely correct with your thoughts of it being the starting point. You are also correct in realizing that the tests are kind of “individually” testing the parts of the logic. Although it just so happens that when you instantiate a Car object, the whole lot of the code fires up into motion. If I wanted to do this in another way, I could have created Car objects in the public static void main method, but I just chose to use @Test methods to run the code.

As for the singleton question, the reason why this is a singleton is that the code private static final AssemblyLine INSTANCE = new AssemblyLine() is declared in the instance variable section of the Class file. This code will only be run once (as per the rules of Java), and it will be run when something called the Java class loader decides to start working with the AssemblyLine Class.

As always, you have some excellent questions Steve, if you need me to elaborate on anything else, just ask :)

Reply

Steve Brouillard January 18, 2013 at 12:44 pm

Thanks for the clarifications Trevor – confusion was beginning to cloud my thought process. I am very interested in seeing how you went about solving this one. I was able to start at a couple of methods that were simple and began to peel back a little bit from that point until I got stuck. I did notice that in the interface Component, you had a comment in the build method to use the thread.sleep method but you used the thread.sleep method in the run() method – think I might have taken that comment a bit too literally. I think the confusion really set in for me because I did not see a starting or an ending point and I was unable to get a handle on the flow of the code if that makes any sense. Was I the only peanut in the peanut gallery to experience this? (come on now … misery would really like a little company on this one) Today, I’m going to sit down and dissect your solution line by line until I understand …

Reply

Trevor Page January 18, 2013 at 1:09 pm

One of the other readers pointed out a few flaws in my code:

1) I could have rid my solution of some repetitive code, I have pretty much the same code for all my Component Classes.
2) I used a public boolean assemblyLineWorking variable, I also say that you should use encapsulation and make your instance variables private. In this case I started my solution with that variable being private but then changed it near the end to make some of the unit tests work properly… so really, this variable should have been private and I should have allowed access to it via getter/setter methods.

Keep in mind that this is NOT an easy assignment, and I meant for it to be difficult on purpose, because these kinds of struggles is what enables students to learn a lot.

Reply

Steve Brouillard January 20, 2013 at 12:23 pm

Quick question on how a LinkedList functions: The method poll() appears to get a value from the head of the cue. How is the head of the cue defined – first value added or the last value added? If I am reading the documentation correctly, it says that this order can be defined. How do you define an order that is different from the default? I read quite a bit of detail about this data structure that talks about overhead for an ArrayList and a LinkedList that really did not mean much to me. What are the conditions that would sway you to use either data structure over the other? Would using only an ArrayList work in this situation? Thanks in advance for any enlightenment!

Reply

Trevor Page January 20, 2013 at 2:04 pm

A LinkedList is First-in-first-out (FIFO), which means that the element at the head of the queue is the first one added, therefore when you “poll” for it, that’s the one that gets returned. The order of a LinkedList can be changed by implementing your own Comparator.

For the most part in my professional career I would always choose to use an ArrayList over a LinkedList, however, for this particular assignment I wanted to use the idea of a Queue. In Java, a Queue is an interface, so you can’t instantiate this, instead you need to search through other data structures that implement the Queue interface. I’m familiar with how the LinkedList works, so I chose to use it.

Reply

Leave a Comment

Powered by sweetCaptcha


Previous post:

Next post: