1.07k likes | 1.09k Views
Learn how to overcome concurrency challenges in Java with advanced programming techniques. Explore the differences between multithreading and single-tasking systems and discover the benefits of parallel processing. Get insights on Java's high-level API for multithreading.
E N D
Threads AdvancedProgramming in Java MehdiEinali
Agenda • Concurrency • Threads in java • Problems in concurrency • Solution for problems in concurrency • Problems in Solutions for problems in concurrency • Java High-level API for concurrency
Sequential Programming • Up to this point, we learned sequential programming. • Everything in a program happens one step at a time. • What is wrong with this approach?
Multitasking vs single task • A single-tasking system can only run one program at a time, while a multi-tasking operating system allows more than one program to be running in concurrency. • Single task OS: • Multiple task OS:
Concurrency vs. Parallelism CPU CPU1 CPU2
Thread vsprocess • A process is an executing instance of an program. • Processes contain their own state information, use their own address spaces, and only interact with each other via inter-process communication mechanisms (generally managed by the operating system) • A thread is a single sequence of execution within a program • Threads within a process share the same state and same memory space, and can communicate with each other directly, because they share the same variables
Jvm is multi threaded CPU Process 1 Process 2 Process 3 Process 4 main run GC
Multithreading • A thread is a single sequence of execution within a program • Multithreadingrefers to multiple threads of control within a single program • each program can run multiple threads of control within it, e.g., Web Browser
What are Threads Good For? • To maintain responsiveness of an application during a long running task. • To enable cancellation of separable tasks. • Some problems are intrinsically parallel. • To monitor status of some resource (DB).
Parallel Processing • Multi-Processor Systems • Multi-core CPUs • Dual core • Core2duo • Corei7, corei5 • Even with no multi-core processors, Multithreading is useful • How? • I/O bounded tasks • Responsive UI • Simulated multi-threading
Language Support • Some languages have no built-in mechanism for muli-threading • C, C++, … • QT as a solution • OS-dependent libraries • pthread in linux • Windows API • Java has multi-threading in its core language • Pros and cons
Application Thread • When we execute an application: • The JVM creates a Thread object whose task is defined by the main() method • It starts the thread • The thread executes the statements of the program one by one until the method returns and the thread dies
Multiple Threads in an Application • Each thread has its private run-time stack • If two threads execute the same method, each will have its own copy of the local variables the methods uses • However, all threads see the same dynamic memory (heap) • Two different threads can act on the same object and same static fields concurrently
Creating Threads • There are two ways to create our own Thread object • Subclassing the Thread class and instantiating a new object of that class • Implementing the Runnable interface • In both cases the run() method should be implemented
Extending Thread publicclassThreadExampleextends Thread { publicvoid run() { for (int i = 1; i <= 100; i++) { System.out.println("Thread: " + i); } } }
Thread Methods void start() • Creates a new thread and makes it runnable • This method can be called only once void run() • The new thread begins its life inside this method
Thread Methods • sleep(intm)/sleep(intm,intn) • The thread sleeps for m milliseconds, plus n nanoseconds • yield() • Causes the currently executing thread object to temporarily pause and allow other threads to execute • Allow only threads of the same priority to run • Nothing is guaranteed for this method
Implementing Runnable publicclassRunnableExample implements Runnable { publicvoid run () { for (int i = 1; i <= 100; i++) { System.out.println ("Runnable: " + i); } } }
A Runnable Object • The Thread object’s run() method calls the Runnable object’s run() method • Allows threads to run inside any object, regardless of inheritance
Starting the Threads publicclassThreadsStartExample { publicstaticvoid main (String argv[]) { newThreadExample ().start (); new Thread(newRunnableExample ()).start (); } }
Ready queue Newly created threads Currently executed thread • Waiting for I/O operation to be completed • Waiting to be notified • Sleeping • Waiting to enter a synchronized section Scheduling Threads start() I/O operation completes What happens when a program with a ServerSocket calls accept()?
Thread State Diagram Alive Running new ThreadExample(); while (…) { … } New Thread Runnable Dead Thread thread.start(); run() method returns Blocked Object.wait() Thread.sleep() blocking IO call waiting on a monitor
classThreadExampleextends Thread { publicvoid run() { MultiThreading.task("Thread"); } } classRunnableExampleimplements Runnable{ publicvoid run() { MultiThreading.task("Runnable"); } } publicclassMultiThreading { publicstaticvoid task(String taskName){ for (int i = 1; i <= 10; i++) { System.out.println(taskName + ": " + i); try { Thread.sleep(new Random().nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); }}}
Running the Threads ThreadExample thr1 = newThreadExample(); thr1.start(); RunnableExample run1 = newRunnableExample(); new Thread(run1).start(); ThreadExample thr2 = newThreadExample(); thr2.start(); RunnableExample run2 = newRunnableExample(); new Thread(run2).start();
Output • First Run • Second Run … • Thread: 7 • Runnable: 7 • Thread: 9 • Runnable: 9 • Thread: 10 • Thread: 8 • Runnable: 8 • Runnable: 10 • Thread: 9 • Runnable: 9 • Runnable: 10 • Thread: 10 … • Thread: 8 • Runnable: 9 • Thread: 9 • Runnable: 7 • Thread: 8 • Runnable: 8 • Thread: 9 • Thread: 10 • Runnable: 10 • Thread: 10 • Runnable: 9 • Runnable: 10
GUI Example • Start Counting starts counting the counter • Stop Counting stops counting the counter
Unresponsive UI StartButton: startButton.addActionListener(newActionListener() { publicvoidactionPerformed(ActionEventevt) { this.stop= false; for (int i = 0; i < 100000; i++) { if(this.stop) break; tfCount.setText("" + countValue); countValue++; } } });
Unresponsive UI (2) StopButton: stopButton.addActionListener(newActionListener() { publicvoidactionPerformed(ActionEvente) { this.stop= true; } });
Responsive UI btnStart.addActionListener(newActionListener() { publicvoidactionPerformed(ActionEventevt) { this.stop= false; Thread counter = newCounterThread(); counter.start(); } }); • Inner class classCounterThreadextends Thread { publicvoid run() { for (int i = 0; i < 100000; i++) { if(this.stop){ break;} tfCount.setText("" + countValue); countValue++; try { sleep(10); } catch (InterruptedException ex) {} } } }
Responsive UI btnStart.addActionListener(newActionListener() { publicvoidactionPerformed(ActionEventevt) { this.stop= false; newThread() { publicvoid run() { for (int i = 0; i < 100000; i++) { if(this.stop){ break;} tfCount.setText("" + countValue); countValue++; try { sleep(10); } catch (InterruptedException ex) {} } } }.start(); } }); • Define anonymous inner class • Create object • Start thread
Java Scheduling • Thread scheduling is the mechanism used to determine how runnable threads are allocated CPU time • Scheduler is based on priority of threads • The priority of a thread : the importance of a thread to the scheduler • Uses fixed-priority scheduling: • Threads are scheduled according to their priority • Priority is compared with other threads in the ready queue
Thread Priority • The scheduler will lean toward running the waiting thread with the highest priority first • Lower-priority threads just tend to run less often • The exact behavior depends on the platform • Usually, all threads should run at the default priority • Trying to manipulate thread priorities is usually a mistake
Thread Priority (2) • Every thread has a priority • When a thread is created, it inherits the priority of the thread that created it • The priority values range from 1 to 10, in increasing priority
Thread Priority (3) • The priority can be adjusted subsequently using the setPriority() method • The priority of a thread may be obtained using getPriority() • Priority constants are defined: • MIN_PRIORITY=1 • MAX_PRIORITY=10 • NORM_PRIORITY=5
Some Notes • Thread implementation in Java is actually based on operating system support • Some Windows operating systems support only 7 priority levels, so different levels in Java may actually be mapped to the same operating system level
Daemon Threads • Daemon threads are “background” threads, that provide services to other threads, e.g., the garbage collection thread • The Java VM will not exit if non-Daemon threads are executing • The Java VM will exit if only Daemon threads are executing • Daemon threads die when the Java VM exits • A thread becomes a daemon with setDaemon() method
quiz • Which one is impossible output? • A) 1234567 • B) 3416527 • C) 1334567 • D) 7654321 • E) 0124567 • F) none of them
Shared data • An object in a program can be changed by more than one thread • Q: Is the order of changes that were preformed on the object important?
Race Condition • A race condition –the outcome of a program is affected by the order in which the program's threads are allocated CPU time • Two threads are simultaneously modifying a single object • Both threads “race” to store their value
Race Condition Example Read A Decrement A Check Condition(B) Increment(B) Check Condition(C) Increment(C) Read A Decrement A Check Condition(B) Increment(A) B C A