980 likes | 991 Views
This program demonstrates how to use multithreading in Java, specifically focusing on creating threads and implementing network programming. It covers topics such as TCP/IP protocols, URL read/write, and socket programming.
E N D
Programming in Java Thread, Network programming 蔡文能 交通大學資訊工程學系 tsaiwn@csie.nctu.edu.tw
Agenda • Threads and Multithreading • Creating a Thread • extending the Thread class • implementing the Runnable interface • Deadlock and Synchronization in Threads • Network Programming • TCP/IP protocols • URL : read/write • Socket programming
Thread vs. Process • A thread (執行緒; 線程)is a single stream of execution within a process. • A process (行程; 執行中的程式)is a program executing in its own address space(位址空間, 例如 0 ~ 65535). • You have been using threads all along. • The main control or execution of all the programs up until • now were controlled by a single thread. • What we want to look at is mutlithreading or having multiple threads executing within the same program.
TestTea.java (1/3) //TestTea.java --- by tsaiwn@csie.nctu.edu.tw ///This program demostrates how to use Thread in Java. ///But there are two problems: ///(1) stop() is unsafe. This might crash the program.(多 Run 幾次試試) /// We should tell thread to die by using a flag instead of /// using stop( ) to kill the thread. ///(2)concurrent access to TestTea.n might cause synchronization problem. /// Codes access to the same variable should be monitored by using /// a synchronized block to mark as a Critical Section. To use Thread SAFELY, Please See TeaOK.Java
TestTea.java (2/3) public class TestTea { protected static long n = 0; public static void main(String[]x) throws Exception{ Tea t1 = new Tea(); Coffee t2 = new Coffee(); t1.start( ); t2.start( ); while(true){ Thread.sleep(13); if(n > 10){ t1.stop( ); t2.stop( ); break; } } // while System.out.println("Thank you and Bye!"); } }
TestTea.java (3/3) class Coffee extends Thread { public void run( ) { while(true){ System.out.println("Drink Coffee "+ ++TestTea.n); // yield( ); } } // run } class Tea extends Thread{ public void run( ){ while(true){ System.out.println("Drink Tea "+ ++TestTea.n); // yield( ); } } // run }
Multitasking and Multithreading • Multitasking: • - having more than one program working at what seems to be at the same time (running concurrently). • - The OS assigns the CPU to the different programs in a manner to give the impression of concurrency. • - There are two types of multitasking – • preemptive and cooperative multitasking. • Multithreading: • - extends the idea of multitasking by allowing individual programs to have what appears to be multiple tasks. • - Each task within the program is called a thread.
How to create Java Thread (1/2) • Java has multithreading built into it. • Java provides a Thread class for handling threads. • There are two ways to create Thread objects • - creating objects from subclasses of the Java Thread class • - implementing the Runnable interface for an object class ThreadX extends Thread { public void run( ) { //logic for the thread } } Thread ThreadSubclass ThreadX tx = new ThreadX( ); tx.start( );
How to create Java Thread (2/2) - implementing the Runnable interface for an object Runnable class RunnableY implementsRunnable { public void run ( ) { //logic for the thread } } implements SomeSubclass RunnableY ry = new RunnableY(); Thread ty = new Thread(ry); ty.start(); In both methods, the run( ) method should be implemented.
Thread Class • The Thread class is part of the java.lang package. • Using an object of this class, the corresponding thread can • be stopped, paused, and resumed. • There are many constructors and methods for this class, we • will look at a few of them: • - Thread( String n) - creates a new Thread with the name n. • - Thread( Runnable target) - creates a new Thread object. • - Thread( Threadgroup group, Runnable target) • This creates a new Thread object in the specified Threadgroup.
Methods in Thread Class instance methods: getPriority( ); setPriority( ); start( ); stop( ); (deprecated) run( ); isAlive( ); suspend( ); resume( ); join( ); static methods: activeCount(); currentThread(); sleep(); yield();
Creating Threads (1/4) • Creating a thread by subclassing the Thread class • This method will allow only five thread to be started in an • object. • public class SimpleThread extends Thread{ • private int countDown = 3; • private static int threadCount = 0; • private int threadNumber = ++threadCount; • public SimpleThread( ) { • System.out.println("Making" + threadNumber++); • }
Creating Threads (2/4) public void run( ) { while(true) { System.out.println("Thread " + threadNumber + " (" + countDown + ") "); if (--countDown == 0) return; } } public static void main(String[] args) { for (int i = 0; i < 5; i++) new SimpleThread( ).start( ); System.out.println("All Threads Started"); } }
Creating Threads (3/4) • One possible output of ‘SimpleThread’: • Making 1 All Threads Started • Making 2 Thread 2(3) • Making 3 Thread 2(2) • Making 4 Thread 6(3) • Making 5 Thread 3(2) • Thread 3(3) Thread 2(1) • Thread 4(3) Thread 6(2) • Thread 4(2) Thread 6(1) • Thread 4(1) Thread 3(1) • Thread 5(3) • Thread 5(2) • Thread 5(1)
2(3) 5(3) 6(3) 3(3) 4(3) 2(2) 5(2) 6(2) 4(2) 3(2) 6(1) 5(1) 4(1) 3(1) 2(1) Creating Threads (4/4) • One possible output of ‘SimpleThread’: Tmain T0 T1 T2 T3 T4 Making 1 Making 5 Making 2 Making 3 Making 4 All Thread started
Synchronization in Threads (1/5) • Synchronization is a mechanism to control the the • execution of different threads so that: • - when multiple threads access a shared variable, proper • execution can be assured. • Java has the synchronized keyword - this can be used to • identify a segment of code or method that should be • accessible to just a single thread at a time. • Before entering a synchronization region, a thread should obtain the semaphore associated with that region – if it is already taken, then the thread blocks (waits) until the semaphore is released.
Synchronization in Threads (2/5) • class Account{ • private int balance = 0; • synchronized void deposit(int amount) { • balance += amount; • } • } • class Customer extends Thread { • Account account; • Customer(Account account) { • this.account = account; • } • public void run() { • try { for (int i = 0; i < 10000; i++) • {account.deposit(10);} • }
Synchronization in Threads (3/5) • catch (Exception e) { • e.printStackTrace(); • } • } /* run */ • } /* Customer */ • public class BankDemo { • private final static int NUMCUSTOMER = 10; • public static void main(String args[ ]) { • //Create account • Account account = new Account(); • //Create and start customer threads • Customer customer[ ] = new Customer[NUMCUSTOMER]; • for (int i = 0; i < NUMCUSTOMER; i++) { • customer[i] = new Customer(account); • customer[i].start( ); • }
Synchronization in Threads (4/5) • //Wait for customer threads to complete • for (int i = 0; i < NUMCUSTOMER; i++) { • try { • customer[i].join( ); • } • catch (InterruptedException e) { • e.printStackTrace( ); • } • } • //Display account balance • System.out.println(account.getBalance( ) ); • } • }
Synchronization in Threads (5/5) • In Java, any object with one or more synchronized methods is a monitor. • When threads call a synchronized method, only one thread is let in at a time, the others wait in a queue. • In producer- consumer type applications, consumer threads might find that there is not enough elements to consume • It is the job of the monitor to ensure that the threads that are waiting for the producer are notified once the elements are produced.
Thread Communication (1/6) • A thread can temporarily release a lock so other threads can have an opportunity to execute a synchronized method. • It is because the Object class defined three methods that allow threads to communicate with each other. • - void wait( ) - causes the thread to wait until notified - this method • can only be called within a synchronized method. • - void wait(long msec) throws InterruptedException • - void wait(long msec, int nsec) throws InterruptedException • - void notify( ) - notifies a randomly selected thread waiting for a lock on this object - can only be called within a synchronized • method. • - void notifyall( ) - notifies all threads waiting for a lock on this object - can only be called within a synchronized method.
Thread Communication (2/6) • class Producer extends Thread { • Queue queue; • Producer (Queue queue) { • this.queue = queue; • } • public void run( ) { • int i = 0; • while(true) { • queue.add(i++); • } • } • }
Thread Communication (3/6) • class Consumer extends Thread { • String str; • Queue queue; • Consumer (String str, Queue queue) { • this.str = str; • this.queue = queue; • } • public void run( ) { • while(true) { • System.out.println(str + ":" + queue.remove( ) ); • } • } • }
Thread Communication (4/6) • class Queue { • private final static int SIZE = 10; • int array[ ] = new int[SIZE]; • int r = 0; • int w = 0; • int count = 0; • synchronized void add(int i) { • //wait while the queue is full • while (count == SIZE) { • try { • wait( ); • } • catch (InterruptedException ie) { • ie.printStackTrace( ); • System.exit(0); • }} /* add */
Thread Communication (5/6) • //Add data to array and adjust write pointer • array[w++] = i; • if (w >= SIZE) • w = 0; • //Increment count • ++count; • //Notify waiting threads • notifyAll( ); • } • synchronized int remove( ) { • //wait while the queue is empty • while (count == 0) { • try { wait( ); } • catch (InterruptedException ie) { • ie.printStackTrace( ); • System.exit(0);}}
Thread Communication (6/6) • //read data from array and adjust read pointer • int element = array[r++]; • if (r >= SIZE) • r = 0; • //Decrement count • --count; • //Notify waiting threads • notifyAll( ); return element; • }} • public class ProducerConsumer { • public static void main(String args[ ]) { • Queue queue = new Queue( ); • new Producer(queue).start( ); • new Consumer("ConsumerA", queue).start( ); • new Consumer("ConsumerB", queue).start( ); • new Consumer("ConsumerC", queue).start( );}}
Thread Lifecycle 藍色的是 deprecated Active sleep(time) Blocked wake up Born JVM yield( ) suspend() start( ) Runnable resume() stop( ) wait( ) stop( ) return( ) return( ) notify( ) Dead block on I/O I/O complete
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Wait/Notify Sequence Lock Object 3. produceResource() 1. synchronized(lock){ 4. synchronized(lock) { 2. lock.wait(); 5. lock.notify(); 9. consumeResource(); 6.} 10. } 7. Reacquire lock 8. Return from wait() Consumer Thread Producer Thread
Scheduling : preemptive vs. nonpreemptive • Thread scheduling is the mechanism used to determine how runnable threads are allocated CPU time • A thread-scheduling mechanism is either preemptive or nonpreemptive • Preemptive scheduling – the thread scheduler preempts (pauses) a running thread to allow different threads to execute • Nonpreemptive scheduling– the scheduler never interrupts a running thread • The nonpreemptive scheduler relies on the running thread to yield control of the CPU so that other threads may execute
Starvation • Nonpreemptive scheduler may cause starvation(runnable threads, ready to be executed, wait to be executed in the CPU a lot of time, maybe even forever) • Sometimes, starvation is also called livelock
Deadlock • Deadlock • Deadlock is an error that can be encountered in multithreads. • It occurs when two or more threads wait indefinitely for each other to relinquish locks. • - Assume that thread-1 holds a lock on object-1 and waits for a lock on object-2. Thread-2 holds a lock on object-2 and waits for a lock on object-1. • - Neither of these threads may proceed. Each waits forever for the other to relinquish the lock it needs.
Thread Priority • The priority values range from 1 to 10, in increasing priority
Thread Priority • Every thread has a priority • When a thread is created, it inherits the priority of the thread that created it • 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
Networking Basics • Java network program is in the application layer. • Using the classes in the java.net package. • Don't need to concern yourself with the TCP and UDP layers.
TCP/IP 網路通訊協定 de facto Standard (業界標準) • TCP/IP network model Layer Function Application End-user application programs Transport Communication among programs on a net (TCP/UDP) Network Basic communication, addressing, and routing (IP, ICMP) Link(Data Link) Network hardware and device drivers(ARP, RARP) 4.應用層 , 3.傳輸層(Transport Layer), 2.網路層, 1.鏈結層(Link Layer) Developed in the US for the Department of Defense ARPAnet system and has becomea defactostandard used by many vendors.
arp rlogin, talk, ftp, DNS NFS, DNS traceroute TCP UDP IP ICMP ARP, Device Drivers Ethernet Header IP Header TCP Header Application Data Ethernet Trailer ETHERNET FRAME TCP/IP網路通訊協定 Layer 4 3 2 1
常見名詞術語 • MAC Address 00-D0-B7-25-3F-A8 • IP Address140.113.2.138 • Prot # TCP 21 (for FTP) • FQDNftp.csie.nctu.edu.tw • DNS Server Domain Name Service • Gateway 閘道口, LAN與WAN交界口 • Router, Switch, Hub • Layer 3 Switch ==~~ Router tsaiwn@csie.nctu.edu.tw
CSMA/CDCarrier Sense Multiple AccesswithCollision Detection • Carrier Sense: can tell when another host is transmitting • Multiple Access: many hosts on 1 wire • Collision Detection: can tell when another host transmits at the same time.