Lesson 4.2: Advanced Programming Logic Flashcards

1
Q

What are the two distinct types of multitasking? Define each.

A

There are two distinct types of multitasking: process-based and thread-based. A process is، in essence، a program that is executing. Thus، process-based multitasking is the feature that allows your computer to run two or more programs concurrently. For example، it is process-based multitasking that allows you to run the Java compiler at the same time you are using a text editor or browsing the Internet. In process-based multitasking، a program is the smallest unit of code that can be dispatched by the scheduler. In a thread-based multitasking environment، the thread is the smallest unit of dispatchable code. This means that a single program can perform two or more tasks at once. For instance، a text editor can be formatting text at the same time that it is printing، as long as these two actions are being performed by two separate threads. Although Java programs make use of process-based multitasking environments، process-based multitasking is not under the control of Java. Multithreaded multitasking is.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What are the six states a thread can be in? What is synchronization in thread-based multitasking?

A

A thread can be in one of several states. It can be running. It can be ready to run as soon as it gets CPU time. A running thread can be suspended، which is a temporary halt to its execution. It can later be resumed. A thread can be blocked when waiting for a resource. A thread can be terminated، in which case its execution ends and cannot be resumed. Along with thread-based multitasking comes the need for a special type of feature called synchronization، which allows the execution of threads to be coordinated in certain well-defined ways. Java has a complete subsystem devoted to synchronization.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is the name of a thread that all processes have?

A

All processes have at least one thread of execution، which is usually called the main thread، because it is the one that is executed when your program begins.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What are the two ways you can a runnable thread object?

A

Java defines two ways in which you can create a runnable object: You can implement the Runnable interface. You can extend the Thread class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is the run() thread and how do you use it?

A

You can construct a thread on any object that implements the Runnable interface. Runnable defines only one method called run( )، which is declared like this: public void run() Inside run( )، you will define the code that constitutes the new thread. It is important to understand that run( ) can call other methods، use other classes، and declare variables just like the main thread. The only difference is that run( ) establishes the entry point for another، concurrent thread of execution within your program. This thread will end when run( ) returns.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

After you create a class that implements Runnable، what do you do?

A

After you have created a class that implements Runnable، you will instantiate an object of type Thread on an object of that class. Thread defines several constructors.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is the Thread(Runnable threadOb) and how do you start it?

A

Thread(Runnable threadOb) In this constructor، threadOb is an instance of a class that implements the Runnable interface. This defines where execution of the thread will begin. Once created، the new thread will not start running until you call its start( ) method، which is declared within Thread. In essence، start( ) executes a call to run( ). The start( ) method is shown here: void start( )

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

what does the sleep() method do and what is it’s general form?

A

The sleep( ) method causes the thread from which it is called to suspend execution for the specified period of milliseconds. Its general form is shown here: static void sleep(long milliseconds) throws InterruptedException The number of milliseconds to suspend is specified in milliseconds. This method can throw an InterruptedException. Thus، calls to it must be wrapped in a try block. The sleep( ) method also has a second form، which allows you to specify the period in terms of milliseconds and nanoseconds if you need that level of precision. In run( )، sleep( ) pauses the thread for 400 milliseconds each time through the loop. This lets the thread run slow enough for you to watch it execute.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Give me an example of code that creates a new thread and starts running it:

A

Here is an example that creates a new thread and starts it running:

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

When does a multithreaded program stop executing?

A

In a multithreaded program، you often will want the main thread to be the last thread to finish running. As a general rule، a program continues to run until all of its threads have ended. Thus، having the main thread finish last is not a requirement. It is، however، often a good practice to follow

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Why is it not necessary for a thread to store it’s own name? What is the code fragment to work around this? What are the two main advantages the work around?

A

However، there is no need for MyThread to store the name of the thread since it is possible to give a name to a thread when it is created. To do so، use this version of Thread’s constructor: Thread(Runnable threadOb، String name) 386Here، name becomes the name of the thread. You can obtain the name of the thread by calling getName( ) defined by Thread. Its general form is shown here: final String getName( ) Giving a thread a name when it is created provides two advantages. First، there is no need for you to use a separate variable to hold the name because Thread already provides this capability. Second، the name of the thread will be available to any code that holds a reference to the thread.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How do you set the name of a thread after it has been created?

A

You can set the name of a thread after it is created by using setName( )، which is shown here: final void setName(String threadName) Here، threadName specifies the new name of the thread.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What are the two thread variations that can make a thread more convenient to use?

A

there are two variations that can، depending on the situation، make MyThread more convenient to use. First، it is possible for the MyThread constructor to create a Thread object for the thread، storing a reference to that thread in an instance variable. With this approach، the thread is ready to start as soon as the MyThread constructor returns. You simply call start( ) on the Thread instance encapsulated by MyThread. The second variation offers a way to have a thread begin execution as soon as it is created. This approach is useful in cases in which there is no need to separate thread creation from thread execution. One way to accomplish this for MyThread is to provide a static factory method that: 1. creates a new MyThread instance، 2. calls start( ) on the thread associated with that instance، 3. and then returns a reference to the newly created MyThread object. With this approach، it becomes possible to create and start a thread through a single method call. This can streamline the use of MyThread، especially in cases in which several threads must be created and started.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What are factory methods?

A

In general، a factory method is a method that returns an object of a class. Typically، factory methods are static methods of a class. Factory methods are useful in a variety of situations. createAndStart( )، a factory method enables an object to be constructed and then set to some specified state prior to being returned to the caller. Another type of factory method is used to provide an easy-to-remember name that indicates the variety of object that is being constructed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Try This 11-1 Extending Thread

A

// This code has been untest and will need it before finalization. // From page 389 in Java: A Beginner’s Guide by Herbert Schildt Implementing Runnable is one way to create a class that can instantiate thread objects. Extending Thread is the other. In this project، you will see how to extend Thread by creating a program functionally similar to the UseThreads program shown at the start of this chapter. When a class extends Thread، it must override the run( ) method، which is the entry point for the new thread. It must also call start( ) to begin execution of the new thread. It is possible to override other Thread methods، but doing so is not required. 1. Create a file called ExtendThread.java. Begin this file with the following lines: —————————-/* Try this 11-1 Extend Thread. / class MyThread extends Thread { —————————-Notice that MyThread now extends Thread instead of implementing Runnable. 2. Add the following MyThread constructor: —————————-// Construct a new thread. MyThread(String name) { super(name); // name thread } —————————-Here، super is used to call this version of Thread’s constructor: Thread(String threadName) Here، threadName specifies the name of the thread. As explained previously، Thread provides the ability to hold a thread’s name. Thus، no instance variable is required by MyThread to store the name. 3. Conclude MyThread by adding the following run( ) method: —————————-// Entry point of thread. public void run() { System.out.println(getName() + “ starting.”); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println(“In “ + getName() + “، count is “ + count); } } catch(InterruptedException exc) { System.out.println(getName() + “ interrupted.”); } System.out.println(getName() + “ terminating.”); —————————-Notice the calls to getName( ). Because ExtendThread extends Thread، it can directly call all of Thread’s methods، including the getName( ) method. 4. Next، add the ExtendThread class shown here: —————————-class ExtendThread { public static void main(String args[]) { System.out.println(“Main thread starting.”); MyThread mt = new MyThread(“Child #1”); mt.start(); for(int i=0; i < 50; i++) { System.out.print(“.”); try { Thread.sleep(100); } catch(InterruptedException exc) { System.out.println(“Main thread interrupted.”); } } System.out.println(“Main thread ending.”); } } —————————-In main( )، notice how an instance of MyThread is created and then started with these two lines: —————————-MyThread mt = new MyThread(“Child #1”); Mt.start(); —————————-Because MyThread now implements Thread، start( ) is called directly on the MyThread instance، mt. 5. Here is the complete program. Its output is the same as the UseThreads example، but in this case، Thread is extended rather than Runnable being implemented. —————————-/ Try this 11-1 Extend Thread. */ class MyThread extends Thread { // Construct a new thread. MyThread(String name) { super(name); // name thread } // Entry point of thread. public void run() { System.out.println(getName() + “ starting.”); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println(“In “ + getName() + “، count is “ + count); } } catch(InterruptedException exc) { System.out.println(getName() + “ interrupted.”); } System.out.println(getName() + “ terminating.”); } } class ExtendThread { public static void main(String args[]) { System.out.println(“Main thread starting.”); MyThread mt = new MyThread(“Child #1”); mt.start(); for(int i=0; i < 50; i++) { System.out.print(“.”); try { Thread.sleep(100); } catch(InterruptedException exc) { System.out.println(“Main thread interrupted.”); } } System.out.println(“Main thread ending.”); } } —————————6. When extending Thread، it is also possible to include the ability to create and start a thread in one step by using a static factory method، similar to that used by the ThreadVariations program shown earlier. To try this، add the following method to MyThread: —————————-public static MyThread createAndStart(String name) { MyThread myThrd = new MyThread(name); myThrd.start(); return myThrd; } —————————-As you can see، this method creates a new MyThread instance with the specified name، calls start( ) on that thread، and returns a reference to the thread. To try createAndStart( )، replace these two lines in main( ): —————————-System.out.println(“Main thread starting”); MyThread mt = new MyThread(“Child #1”); —————————-with this line: —————————-MyThread mt = MyThread.createAndStart(“Child #1”); —————————-After making these changes، the program will run the same as before، but you will be creating and starting the thread using a single method call.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What is the more efficient way of creating child threads (by extending Thread or implementing Runnable)?

A

The Thread class defines several methods that can be overridden by a derived class. Of these methods، the only one that must be overridden is run( ). This is، of course، the same method required when you implement Runnable. Some Java programmers feel that classes should be extended only when they are being expanded or customized in some way. So، if you will not be overriding any of Thread’s other methods، it is probably best to simply implement Runnable. Also، by implementing Runnable، you enable your thread to inherit a class other than Thread.

17
Q

What does the isAlive() and join() methods do?

A

Thread provides two means by which you can determine if a thread has ended. First، you can call isAlive( ) on the thread. Its general form is shown here: final boolean isAlive( ) The isAlive( ) method returns true if the thread upon which it is called is still running. It returns false otherwise. Another way to wait for a thread to finish is to call join( )، shown here: final void join( ) throws InterruptedException This method waits until the thread on which it is called terminates. Its name comes from the concept of the calling thread waiting until the specified thread joins it. Additional forms of join( ) allow you to specify a maximum amount of time that you want to wait for the specified thread to terminate.

18
Q

Does a thread with high priority run faster than a thread with low priority?

A

just because you give one thread a high priority and another a low priority does not necessarily mean that one thread will run faster or more often than the other. It’s just that the high-priority thread has greater potential access to the CPU.

19
Q

How do you change the priority of a thread? what are the level values of priority? and what are static final variables?

A

When a child thread is started، its priority setting is equal to that of its parent thread. You can change a thread’s priority by calling setPriority( )، which is a member of Thread. This is its general form: final void setPriority(int level) Here، level specifies the new priority setting for the calling thread. The value of level must be within the range MIN_PRIORITY and MAX_PRIORITY. Currently، these values are 1 and 10، respectively. To return a thread to default priority، specify NORM_PRIORITY، which is currently 5. These priorities are defined as static final variables within Thread.

20
Q

How do you find the priority of a thread?

A

You can obtain the current priority setting by calling the getPriority( ) method of Thread، shown here: final int getPriority( )

21
Q

Does the operating system’s implementation of multitasking affect how much CPU time a thread receives?

A

Aside from a thread’s priority setting، the most important factor affecting thread execution is the way the operating system implements multitasking and scheduling. Some operating systems use preemptive multitasking in which each thread receives a time slice، at least occasionally. Other systems use nonpreemptive scheduling in which one thread must yield execution before another thread will execute. In nonpreemptive systems، it is easy for one thread to dominate، preventing others from running.

22
Q

What is synchronization and when is it most commonly used?

A

When using multiple threads، it is sometimes necessary to coordinate the activities of two or more. The process by which this is achieved is called synchronization. The most common reason for synchronization is when two or more threads need access to a shared resource that can be used by only one thread at a time.

23
Q

What is a monitor and what is a lock generally speaking?

A

Key to synchronization in Java is the concept of the monitor، which controls access to an object. A monitor works by implementing the concept of a lock. When an object is locked by one thread، no other thread can gain access to the object. When the thread exits، the object is unlocked and is available for use by another thread.

24
Q

What does the synchronized keyword do? Give me a code example that it is used in.

A

You can synchronize access to a method by modifying it with the synchronized keyword. When that method is called، the calling thread enters the object’s monitor، which then locks the object. While locked، no other thread can enter the method، or enter any other synchronized method defined by the object’s class. When the thread returns from the method، the monitor unlocks the object، allowing it to be used by the next thread. Thus، synchronization is achieved with virtually no programming effort on your part. The following program demonstrates synchronization by controlling access to a method called sumArray( )، which sums the elements of an integer array.

25
Q

How does a method become locked?

A

A synchronized method is created by preceding its declaration with synchronized. For any given object، once a synchronized method has been called، the object is locked and no synchronized methods on the same object can be used by another thread of execution. Other threads trying to call an in-use synchronized object will enter a wait state until the object is unlocked. When a thread leaves the synchronized method، the object is unlocked.

26
Q

If you have a class in which you dont have access to the source code، how do you synchronize the class?

A

Fortunately، the solution to this problem is quite easy: You simply put calls to the methods defined by this class inside a synchronized block. This is the general form of a synchronized block: synchronized(objref) { // statements to be synchronized } Page 406Here، objref is a reference to the object being synchronized. Once a synchronized block has been entered، no other thread can call a synchronized method on the object referred to by objref until the block has been exited.

27
Q

In certain cases، you wont be able to use the source code which could be a problem if you need synchronization. Give me an example of code that uses calls to work around this.

A

For example، another way to synchronize calls to sumArray( ) is to call it from within a synchronized block، as shown in this version of the program:

28
Q

What are the “concurrency utilities”? Also، what is the Fork/Join Framework?

A

The concurrency utilities، which are packaged in java.util.concurrent (and its subpackages)، support concurrent programming. Among several other items، they offer synchronizers، thread pools، execution managers، and locks that expand your control over thread execution. One of the most exciting features of the concurrent API is the Fork/Join Framework. The Fork/Join Framework supports what is often termed parallel programming. This is the name commonly given to the techniques that take advantage of computers that contain two or more processors (including multicore systems) by subdividing a task into subtasks، with each subtask executing on its own processor. As you can imagine، such an approach can lead to significantly higher throughput and performance. The key advantage of the Fork/Join Framework is ease of use; it streamlines the development of multithreaded code that automatically scales to utilize the number of processors in a system. Thus، it facilitates the creation of concurrent solutions to some common programming tasks، such as performing operations on the elements of an array.

29
Q

What do the The wait( )، notify( )، and notifyAll( ) methods do? How do you use them? What are code fragments for them?

A

The wait( )، notify( )، and notifyAll( ) methods are part of all objects because they are implemented by the Object class. These methods should be called only from within a synchronized context. Here is how they are used. When a thread is temporarily blocked from running، it calls wait( ). This causes the thread to go to sleep and the monitor for that object to be released، allowing another thread to use the object. At a later point، the sleeping thread is awakened when some other thread enters the same monitor and calls notify( )، or notifyAll( ). Following are the various forms of wait( ) defined by Object: final void wait( ) throws InterruptedException final void wait(long millis) throws InterruptedException final void wait(long millis، int nanos) throws InterruptedException The first form waits until notified. The second form waits until notified or until the specified period of milliseconds has expired. The third form allows you to specify the wait period in terms of nanoseconds. Page 409Here are the general forms for notify( ) and notifyAll( ): final void notify( ) final void notifyAll( ) A call to notify( ) resumes one waiting thread. A call to notifyAll( ) notifies all threads، with the scheduler determining which thread gains access to the object. Before looking at an example that uses wait( )، an important point needs to be made. Although wait( ) normally waits until notify( ) or notifyAll( ) is called، there is a possibility that in very rare cases the waiting thread could be awakened due to a spurious wakeup. The conditions that lead to a spurious wakeup are complex and beyond the scope of this book. However، the Java API documentation recommends that because of the remote possibility of a spurious wakeup، calls to wait( ) should take place within a loop that checks the condition on which the thread is waiting.

30
Q

What happens when you don’t run a final wait() call in a program that depends on it?

A

Thus، a final call to notify( ) is required in order for the waiting method to run. As an experiment، try removing this call to notify( ) and watch what happens. As you will see، the program will “hang،” and you will need to press CTRL-C to exit. The reason for this is that when the final call to tock( ) calls wait( )، there is no corresponding call to notify( ) that lets tock( ) conclude. Thus، tock( ) just sits there، waiting forever.

31
Q

What does the term “deadlock” mean?

A

Deadlock is، as the name implies، a situation in which one thread is waiting for another thread to do something، but that other thread is waiting on the first. Thus، both threads are suspended، waiting on each other، and neither executes. This situation is analogous to two overly polite people، both insisting that the other step through a door first!

32
Q

What is a “race condition”?

A

A race condition occurs when two (or more) threads attempt to access a shared resource at the same time، without proper synchronization. For example، one thread may be writing a new value to a variable while another thread is incrementing the variable’s current value. Without synchronization، the new value of the variable will depend upon the order in which the threads execute. (Does the second thread increment the original value or the new value written by the first thread?) In situations like this، the two threads are said to be “racing each other،” with the final outcome determined by which thread finishes first. Like deadlock، a race condition can occur in difficult-to-discover ways. The solution is prevention: careful programming that properly synchronizes access to shared resources.