1 / 92

Essential Java classes

Essential Java classes. mainly classes in the java.lang and java.io packages. Contents. Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources. Exceptions.

lore
Télécharger la présentation

Essential Java classes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Essential Java classes mainly classes in the java.lang and java.io packages

  2. Contents • Handling errors using exceptions • Multi-threading • I/O • Setting program attributes • Accessing system resources

  3. Exceptions • The Java programming language uses exceptions to provide error-handling capabilities for its programs • An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions • When an error occurs within a method, the method creates an object and hands it off to the runtime system • The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred • Creating an exception object and handing it to the runtime system is called throwing an exception

  4. Exception handling

  5. //Note: This class won't compile by design! import java.io.*; import java.util.Vector; public class ListOfNumbers { private Vector victor; private static final int SIZE = 10; public ListOfNumbers () { victor = new Vector(SIZE); for (int i = 0; i < SIZE; i++) { victor.addElement(new Integer(i)); } } public void writeList() { PrintWriter out = new PrintWriter( new FileWriter("OutFile.txt")); for (int i = 0; i < SIZE; i++) { out.println("Value at: " + i + " = " + victor.elementAt(i)); } out.close(); } }

  6. private Vector victor; private static final int SIZE = 10; PrintWriter out = null; try { System.out.println("Entered try statement"); out = new PrintWriter(new FileWriter("OutFile.txt")); for (int i = 0; i < SIZE; i++) { out.println("Value at: " + i + " = " + victor.elementAt(i)); } } catch and finally statements . . .

  7. Catch exceptions • try { } catch (FileNotFoundException e) { System.err.println("FileNotFoundException: " + e.getMessage()); throw new SampleException(e); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); }

  8. Finally • finally { if (out != null) { System.out.println("Closing PrintWriter"); out.close(); } else { System.out.println("PrintWriter not open"); } }

  9. Specify exceptions thrown by methods • public void writeList() throws IOException { PrintWriter out = new PrintWriter( new FileWriter("OutFile.txt")); for (int i = 0; i < SIZE; i++) { out.println("Value at: " + i + " = " + victor.elementAt(i)); } out.close(); }

  10. Throw exceptions • public Object pop() throws EmptyStackException { Object obj; if (size == 0) { throw new EmptyStackException(); } obj = objectAt(SIZE - 1); setObjectAt(SIZE - 1, null); size--; return obj; }

  11. Exception classes

  12. Chained exceptions • Relevant constructor and methods • Throwable getCause() • Throwable initCause(Throwable) • Throwable(String, Throwable) • Throwable(Throwable) • try { } catch (IOException e) { throw new SampleException("Other IOException", e); }

  13. Accessing stack trace • catch (Exception cause) { StackTraceElement elements[] = cause.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { System.err.println(elements[i].getFileName() + ":" + elements[i].getLineNumber() + ">> " + elements[i].getMethodName() + "()"); } }

  14. Logging API • try { Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); } catch (IOException e) { Logger logger = Logger.getLogger("package.name"); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0; n = elements.length; i < n; i++) { logger.log(Level.WARNING, elements[i].getMethodName()); } }

  15. Contents • Handling errors using exceptions • Multi-threading • I/O • Setting program attributes • Accessing system resources

  16. Thread • A thread — sometimes called an execution context or a lightweight process — is a single sequential flow of control within a program • A thread is similar to a real process in that both have a single sequential flow of control. However, a thread is considered lightweight because it runs within the context of a full-blown program and takes advantage of the resources allocated for that program • As a sequential flow of control, a thread must carve out some resources within a running program. For example, a thread must have its own execution stack and program counter

  17. A timer • import java.util.Timer; // Simple demo that uses java.util.Timer to // schedule a task to execute once 5 seconds have passed import java.util.TimerTask; public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.format("Time's up!%n"); timer.cancel(); //Terminate the timer thread } } public static void main(String args[]) { new Reminder(5); System.out.format("Task scheduled.%n"); } }

  18. Steps of implementing timer • Implement a custom subclass of TimerTask. The run method contains the code that performs the task. • Create a thread by instantiating the Timer class. • Instantiate the TimerTask object. • Schedule the timer task for execution. • //Get the Date corresponding to 11:01:00 pm today. Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 1); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); timer = new Timer(); timer.schedule(new RemindTask(), time);

  19. Stopping timer thread • Invoke cancel on the timer. You can do this from anywhere in the program, such as from a timer task's run method. • Make the timer's thread a "daemon" by creating the timer like this: new Timer(true). If the only threads left in the program are daemon threads, the program exits. • After all the timer's scheduled tasks have finished executing, remove all references to the Timer object. Eventually, the timer's thread will terminate. • Invoke the System.exit method, which makes the entire program (and all its threads) exit.

  20. public class ReminderBeep { ... public ReminderBeep(int seconds) { toolkit = Toolkit.getDefaultToolkit(); timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.format("Time's up!%n"); toolkit.beep(); //timer.cancel(); //Not necessary because //we call System.exit. System.exit(0); //Stops the AWT thread //(and everything else). } } ... }

  21. Periodic task • public class AnnoyingBeep { Toolkit toolkit; Timer timer; public AnnoyingBeep() { toolkit = Toolkit.getDefaultToolkit(); timer = new Timer(); timer.schedule(new RemindTask(), 0, //initial delay 1*1000); //subsequent rate } class RemindTask extends TimerTask { int numWarningBeeps = 3; public void run() { if (numWarningBeeps > 0) { toolkit.beep(); numWarningBeeps--; } System.exit(0); } } }

  22. Implementing a thread • Subclassing Thread class and overriding run method • public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.format("%d %s%n", i, getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.format("DONE! %s%n", getName()); } }

  23. public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } }

  24. Implement the Runnable interface and its run method and then create a thread with itself as the Thread's target. • public class Clock extends java.applet.Applet implements Runnable { private volatile Thread clockThread = null; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } } } public void stop() { clockThread = null; }

  25. Life cycle of a thread

  26. Life cycle of a thread • A thread is started by its start() method • A thread enters Not Runnable state when one of the following events occurs: • Its sleep method is invoked. • The thread calls the wait method to wait for a specific condition to be satisifed. • The thread is blocking on I/O • A thread should arrange for its own death by having a run method that terminates naturally • Thread.getState() method returns Thread.State values that include: NEW,RUNNABLE, BLOCKED , WAITING, TIMED_WAITING, TERMINATED • The Thread.isAlive() method returns true if the thread has been started and not stopped

  27. Scheduling • The Java runtime environment supports a very simple, deterministic algorithm called fixed-priority scheduling • This algorithm schedules threads on the basis of their priority relative to other Runnable threads • When a thread is created, it inherits its priority from the thread that created it. • In addition, by using the setPriority method, you can modify a thread's priority at any time after its creation. • Thread priorities are integers that range between MIN_PRIORITY and MAX_PRIORITY (constants defined in the Thread class).

  28. Relinquishing the CPU • Writing CPU-intensive code can have negative repercussions on other threads running in the same process. • In general, try to write well-behaved threads that voluntarily relinquish the CPU periodically and give other threads an opportunity to run. • A thread can voluntarily yield the CPU by calling the yield method, which gives other threads of the same priority a chance to run. If no equal-priority threads are Runnable, yield is ignored.

  29. Synchronizing threads • public class Producer extends Thread { private CubbyHole cubbyhole; private int number; public Producer(CubbyHole c, int number) { cubbyhole = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(number, i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }

  30. public class Consumer extends Thread { private CubbyHole cubbyhole; private int number; public Consumer(CubbyHole c, int number) { cubbyhole = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get(number); } } }

  31. Locking an object • public class CubbyHole { private int contents; private boolean available = false; public synchronized int get(int who) { //CubbyHole locked by the Producer. ... //CubbyHole unlocked by the Producer } public synchronized void put(int who, int value) { //CubbyHole locked by the Consumer. ... //CubbyHole unlocked by the Consumer. }

  32. Reentrant lock • The same thread can call a synchronized method on an object for which it already holds the lock, thereby reacquiring the lock • The Java runtime environment allows a thread to reacquire a lock because the locks are reentrant • Reentrant locks are important because they eliminate the possibility of a single thread having to wait for a lock that it already holds

  33. notify and wait methods • public synchronized int get() { //Won't work! if (available == true) { available = false; return contents; } } public synchronized void put(int value) { //Won't work! if (available == false) { available = true; contents = value; } }

  34. public synchronized int get() { while (available == false) { try { //Wait for Producer to put value. wait(); } catch (InterruptedException e) { } } available = false; notifyAll();//Notify Producer that value has been retrieved. return contents; } public synchronized void put(int value) { while (available == true) { try { //Wait for Consumer to get value. wait(); } catch (InterruptedException e) { } } contents = value; available = true;. notifyAll();//Notify Consumer that value has been set }

  35. Running the consumer/producer • public class ProducerConsumerTest { public static void main(String[] args) { CubbyHole c = new CubbyHole(); Producer p = new Producer(c, 1); Consumer c = new Consumer(c, 1); p.start(); c.start(); } }

  36. Explicit lock • An explicit lock is more flexible than using the synchronized keyword because the lock can span a few statements in a method or multiple methods in addition to the scopes (block and method) supported by synchronized • To create an explicit lock, instantiate an implementation of the Lock interface, usually ReentrantLock. To grab the lock, invoke the lock method; to release the lock, invoke the unlock method. You should wrap the lock and unlock methods in a try/finally clause • To wait on an explicit lock, create a condition variable (an object that supports the Condition interface) using the Lock.newCondition method. Condition variables provide the methods await — to wait for the condition to be true, and signal and signalAll — to notify all waiting threads that the condition has occurred

  37. import java.util.concurrent.locks.*; public class CubbyHole2 { private int contents; private boolean available = false; private Lock aLock = new ReentrantLock(); private Condition condVar = aLock.newCondition(); public int get(int who) { aLock.lock(); try { while (available == false) { try { condVar.await(); } catch (InterruptedException e) { } } available = false; condVar.signalAll(); } finally { aLock.unlock(); } return contents; }

  38. public void put(int who, int value) { aLock.lock(); try { while (available == true) { try { condVar.await(); } catch (InterruptedException e) { } } contents = value; available = true; System.out.format("Producer %d put: %d%n", who, contents); condVar.signalAll(); } finally { aLock.unlock(); } }

  39. Synchronized data structure • In your programs, you probably will want to take advantage of the java.util.concurrent package's data structures that hide all the synchronization details

  40. import java.util.concurrent.*; public class Producer3 extends Thread { private BlockingQueue cubbyhole; private int number; public Producer3(BlockingQueue c, int num) { cubbyhole = c; number = num; } public void run() { for (int i = 0; i < 10; i++) { try { cubbyhole.put(i); System.out.format("Producer #%d put: %d%n", number, i); sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }

  41. import java.util.concurrent.*; public class ProducerConsumerTest3 { public static void main(String[] args) { ArrayBlockingQueue c = new ArrayBlockingQueue(1); Producer3 p = new Producer3(c, 1); Consumer3 c = new Consumer3(c, 1); p.start(); c.start(); } }

  42. Thread pool • A thread pool is a managed collection of threads that are available to perform tasks. Thread pools usually provide the following: • Improved performance when executing large numbers of tasks as a result of reduced per-task invocation overhead. • A way of bounding the resources, including threads, consumed when executing a collection of tasks • In addition, thread pools relieve you from having to manage the life cycle of threads. • They allow to take advantage of threading, but focus on the tasks that you want the threads to perform instead of thread mechanics

  43. Thread pool • To use thread pools, instantiate an implementation of the ExecutorService interface and hand it a set of tasks. • The choices of configurable thread pool implementations are ThreadPoolExecutor and ScheduledThreadPoolExecutor. • Recommend using the more convenient factory methods of the Executors class listed in the following table. Factory Methods in the Executors Class newFixedThreadPool(int) Creates a fixed-size thread pool. newCachedThreadPool Creates an unbounded thread pool with automatic thread reclamation. newSingleThreadExecutor Creates a single background thread.

  44. public class WorkerThread implements Runnable { private int workerNumber; WorkerThread(int number) { workerNumber = number; } public void run() { for (int i=0;i<=100;i+=20) { //Perform some work... System.out.format("Worker number: %d, percent complete: %d%n", workerNumber, i); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } } }

  45. import java.util.concurrent.*; public class ThreadPoolTest { public static void main(String[ ] args) { int numWorkers = Integer.parseInt(args[0]); int threadPoolSize = Integer.parseInt(args[1]); ExecutorService tpes = Executors.newFixedThreadPool (threadPoolSize); WorkerThread[ ] workers = new WorkerThread[numWorkers]; for (int i = 0; i < numWorkers; i++) { workers[i] = new WorkerThread(i); tpes.execute(workers[i]); } tpes.shutdown(); } }

  46. import java.util.concurrent.*; public class CallableWorkerThread implements Callable<Integer> { private int workerNumber; CallableWorkerThread(int number) { workerNumber = number; } public Integer call() { for (int i = 0; i <= 100; i += 20) { //Perform some work... System.out.format("Worker number: %d, percent complete: %d%n", workerNumber, i); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } return(workerNumber); } }

  47. public class ThreadPoolTest2 { public static void main(String[] args) { int numWorkers = Integer.parseInt(args[0]); ExecutorService tpes = Executors.newCachedThreadPool(); CallableWorkerThread workers[] = new CallableWorkerThread[numWorkers]; Future<Integer> futures[] = new Future[numWorkers]; for (int i = 0; i < numWorkers; i++) { workers[i] = new CallableWorkerThread(i); futures[i]=tpes.submit(workers[i]); } for (int i = 0; i < numWorkers; i++) { try { System.out.format("Ending worker: %d%n", futures[i].get()); } catch (Exception e) {} } } }

  48. Contents • Handling errors using exceptions • Multi-threading • I/O • Setting program attributes • Accessing system resources

  49. I/O streams

  50. I/O algorithms

More Related