Advanced Java Workshop John Cole Senior Lecturer Computer Science Department The University of Texas at Dallas August 23, 2014 http://www.utdallas.edu/~John.Cole Advanced Java Workshop 1 Topics • Programming Environments • Introduction to classes • Collection classes and generics: Set, List, Queue, Vector, Map • Basic Swing: JFrame, Panels, Labels, Buttons, Text Fields, Combo Boxes, Lists • Event-driven programming • Text and Binary I/O • Multithreading Advanced Java Workshop 2 NetBeans • URL: https://netbeans.org/downloads/7.4/ • Great general-purpose environment for most Java development • UTD doesn’t support 8.0 yet because of java issues, but 7.4 is solid and will do everything you want Advanced Java Workshop 3 Eclipse with ADT • http://developer.android.com/sdk/index.html #download • While you can install the Android Developer Tools in NetBeans, I have had trouble with this • Eclipse is a great general-purpose java environment as well as having the Android tools • Get this if you’re taking CS6301: User Interface Design Advanced Java Workshop 4 Other Resources • Both NetBeans and Eclipse have IntelliSense, but you may need more than that. • Java Docs: http://docs.oracle.com/javase/7/docs/api/ • Java Tutorials: http://docs.oracle.com/javase/tutorial/ Advanced Java Workshop 5 Classes • There are no header files in Java. • The import statement finds packages that your program can use. • When you create a class, the declaration looks like this: public class Rectangle { private double length; private double width; } Advanced Java Workshop 6 Classes • Any methods go in the braces. You don’t need to use prototypes: public class Rectangle { private double length; private double width; Public double getArea() { return length * width; } } Advanced Java Workshop 7 Class Layout Conventions • The suggested organization of a source code file can vary by employer or instructor. • A common organization is: – Fields listed first – Methods listed second • Accessors and mutators are typically grouped. • There are tools that can help in formatting code to specific standards. Advanced Java Workshop 8 Derived Classes • You can derive a new class from an existing one. A common thing to see in a GUI program is: public class MyFrame extends Jframe • You can then write your own constructor and other methods while using everything in JFrame Advanced Java Workshop 9 Interfaces • An interface in java is like an abstract class • You must provide concrete implementations of all methods • The keyword for using an interface is implements • You can implement multiple interfaces public class c implements ActionListener Advanced Java Workshop 10 Arrays • An array in Java is not just a set of memory locations; it is an actual object • You create an array the way you would any object: int[] numbers = new int[6]; • Note that you can have a variable in place of 6, since this is being allocated dynamically Advanced Java Workshop 11 Two-Dimensional Arrays • A 2D array is essentially an array of arrays. Thus you can have: String[][] puzzle; puzzle = new String[5][5]; puzzle[0][0] = “search”; Advanced Java Workshop 12 Ragged Arrays • Since a multidimensional array is an array of arrays, not all rows need contain the same number of columns: int[][] triangle = { {1, 2, 3, 4}, {5, 6, 7}, {8, 9}, {10}}; Advanced Java Workshop 13 Collection Classes • • • • • • • • ArrayList HashSet LinkedHashSet TreeSet Vector Stack Queue HashMap Advanced Java Workshop 14 ArrayList • If you need to support random access through an index without inserting or removing elements from any place other than the end, ArrayList offers the most efficient collection Advanced Java Workshop 15 HashSet • The HashSet class is a concrete class that implements Set. It can be used to store duplicate-free elements. For efficiency, objects added to a hash set need to implement the hashCode method in a manner that properly disperses the hash code. Advanced Java Workshop 16 LinkedHashSet • The elements in the HashSet are not ordered • LinkedHashSet elements can be retrieved in the order in which they were inserted Advanced Java Workshop 17 TreeSet • SortedSet is a subinterface of Set, which guarantees that the elements in the set are sorted. • TreeSet is a concrete class that implements the SortedSet interface. • You can use an iterator to traverse the elements in the sorted order. • The elements can be sorted in two ways. Advanced Java Workshop 18 TreeSet (Continued) • The elements can be sorted in two ways: • One way is to use the Comparable interface. • The other way is to specify a comparator for the elements in the set if the class for the elements does not implement the Comparable interface, or you don’t want to use the compareTo method in the class that implements the Comparable interface Advanced Java Workshop 19 Vector • In Java 2, Vector is the same as ArrayList, except that Vector contains the synchronized methods for accessing and modifying the vector. • None of the new collection data structures introduced so far are synchronized (threadsafe) Advanced Java Workshop 20 Stack • The Stack class represents a last-in-first-out stack of objects • The elements are accessed only from the top of the stack. • You can retrieve, insert, or remove an element from the top of the stack Advanced Java Workshop 21 Queue • A queue is a first-in/first-out data structure • Elements are appended to the end of the queue and are removed from the beginning of the queue Advanced Java Workshop 22 HashMap • Efficient for locating a value, inserting a mapping, and deleting a mapping • Not sorted Advanced Java Workshop 23 Generics • You can specify the data types of the elements of a collection. HashMap h<String, double[]> • This tells the compiler that the HashMap’s key will be a string and its data will be an array of doubles • This is checked at compile time only. Advanced Java Workshop 24 Data Structure Exercise • Write a program that asks for the names and ages of 5 people. Put the information into a HashMap with the name as the key and the age as the data. • Do the same thing using a TreeMap • Print the data from each structure using an iterator Advanced Java Workshop 25 Basic Swing • import javax.swing.* • Swing components are “lightweight” and very portable. • They don’t depend upon the underlying operating system • Don’t use the older AWT (Abstract Windowing Toolkit) controls unless absolutely necessary Advanced Java Workshop 26 JFrame • When writing a GUI program, create a class derived from JFrame. • This lets you do initialization in the constructor • You can create controls that will show in the window, for example Advanced Java Workshop 27 JFrame • Useful things in the constructor: this.setTitle(("Graduate Java Workshop")); this.setSize(500, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLO SE); this.setVisible(true); Advanced Java Workshop 28 Layout Managers • JFrames and other containers can have a layout that defines how contained graphical objects appear • This implies that you can have nested containers, each with its own layout • This was done because Java was intended to be independent of screen resolution Advanced Java Workshop 29 FlowLayout • This is the simplest layout manager. Components are placed left to right, wrapping around at the edge of the container • You can change the way the components are aligned within the flow with constants: CENTER, LEFT, and RIGHT. Advanced Java Workshop 30 FlowLayout Write a program that adds three labels and three text fields into the content pane of a frame with a FlowLayout manager. Advanced Java Workshop 31 The FlowLayout Class java.awt.FlowLayout The get and set methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. -alignment: int The alignment of this layout manager (default: CENTER). -hgap: int The horizontal gap of this layout manager (default: 5 pixels). -vgap: int The vertical gap of this layout manager (default: 5 pixels). +FlowLayout() Creates a default FlowLayout manager. +FlowLayout(alignment: int) Creates a FlowLayout manager with a specified alignment. +FlowLayout(alignment: int, hgap: int, vgap: int) Creates a FlowLayout manager with a specified alignment, horizontal gap, and vertical gap. Advanced Java Workshop 32 GridLayout • Controls are arranged in a grid. You specify the number of rows and columns. frame.setLayout(new GridLayout(3,5)); • One peculiarity is that everything in a grid cell is sized to fit the cell. Advanced Java Workshop 33 GridLayout This example shows using a GridLayout with 3 rows and 2 columns to display the labels and text fields. Advanced Java Workshop 34 The GridLayout Class java.awt.GridLayout The get and set methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. -rows: int The number of rows in this layout manager (default: 1). -columns: int The number of columns in this layout manager (default: 1). -hgap: int The horizontal gap of this layout manager (default: 0). -vgap: int The vertical gap of this layout manager (default: 0). +GridLayout() Creates a default GridLayout manager. +GridLayout(rows: int, columns: int) Creates a GridLayout with a specified number of rows and columns. +GridLayout(rows: int, columns: int, Creates a GridLayout manager with a specified number of rows and hgap: int, vgap: int) columns, horizontal gap, and vertical gap. Advanced Java Workshop 35 BorderLayout The BorderLayout manager divides the container into five areas: East, South, West, North, and Center. Components are added to a BorderLayout by using the add method. add(Component, constraint), where constraint is BorderLayout.EAST, BorderLayout.SOUTH, BorderLayout.WEST, BorderLayout.NORTH, or BorderLayout.CENTER. Advanced Java Workshop 36 BorderLayout Advanced Java Workshop 37 The BorderLayout Class java.awt.BorderLayout The get and set methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. -hgap: int The horizontal gap of this layout manager (default: 0). -vgap: int The vertical gap of this layout manager (default: 0). +BorderLayout() Creates a default BorderLayout manager. +BorderLayout(hgap: int, vgap: int) Creates a BorderLayout manager with a specified number of horizontal gap, and vertical gap. Advanced Java Workshop 38 Panels A JPanel is a container that can be put into another container. • Panels have their own layout Jpanel pnlTop = new JPanel(); pnlTop.setLayout(new GridLayout(4,3)); frame.add(pnlTop); • Note that the panel will be added to the frame’s layout. Advanced Java Workshop 39 Controls • The screen objects you see, such as text fields, labels, checkboxes, buttons, and the like are collectively referred to as controls. Advanced Java Workshop 40 JLabel • This is used to display text or an image, or both • The constructors for labels are as follows: JLabel() JLabel(String text, int horizontalAlignment) JLabel(String text) JLabel(Icon icon) JLabel(Icon icon, int horizontalAlignment) JLabel(String text, Icon icon, int horizontalAlignment) Advanced Java Workshop 41 JTextField A text field is an input area where the user can type in characters. Text fields are useful in that they enable the user to enter in variable data (such as a name or a description). javax.swing.text.JTextComponent The get and set methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. -text: String The text contained in this text component. -editable: boolean Indicates whether this text component is editable (default: true). javax.swing.JTextField -columns: int The number of columns in this text field. -horizontalAlignment: int The horizontal alignment of this text field (default: LEFT). +JTextField() Creates a default empty text field with number of columns set to 0. +JTextField(column: int) Creates an empty text field with specified number of columns. +JTextField(text: String) Creates a text field initialized with the specified text. +JTextField(text: String, columns: int) Creates a text field initialized with the specified text and columns. Advanced Java Workshop 42 JTextField Constructors • JTextField(int columns) Creates an empty text field with the specified number of columns. • JTextField(String text) Creates a text field initialized with the specified text. • JTextField(String text, int columns) Creates a text field initialized with the specified text and the column size. Advanced Java Workshop 43 JTextField Properties • text • horizontalAlignment • editable • columns Advanced Java Workshop 44 JTextField Methods • getText() Returns the string from the text field. • setText(String text) Puts the given string in the text field. • setEditable(boolean editable) Enables or disables the text field to be edited. By default, editable is true. • setColumns(int) Sets the number of columns in this text field. The length of the text field is changeable. Advanced Java Workshop 45 JTextArea If you want to let the user enter multiple lines of text, you cannot use text fields unless you create several of them. The solution is to use JTextArea, which enables the user to enter multiple lines of text. javax.swing.text.JTextComponent The get and set methods for these data fields are provided in the class, but omitted in the UML diagram for brevity. javax.swing.JTextArea -columns: int The number of columns in this text area. -rows: int The number of rows in this text area. -tabSize: int The number of characters used to expand tabs (default: 8). -lineWrap: boolean Indicates whether the line in the text area is automatically wrapped (default: false). -wrapStyleWord: boolean Indicates whether the line is wrapped on words or characters (default: false). +JTextArea() Creates a default empty text area. +JTextArea(rows: int, columns: int) Creates an empty text area with the specified number of rows and columns. +JTextArea(text: String) Creates a new text area with the specified text displayed. +JTextArea(text: String, rows: int, columns: int) Creates a new text area with the specified text and number of rows and columns. Appends the string to text in the text area. +append(s: String): void +insert(s: String, pos: int): void Inserts string s in the specified position in the text area. +replaceRange(s: String, start: int, end: int): void Replaces partial text in the range from position start to end with string s. +getLineCount(): int Returns the Java actual number of lines contained in the text area. Advanced Workshop 46 JTextArea Constructors • JTextArea(int rows, int columns) Creates a text area with the specified number of rows and columns. • JTextArea(String s, int rows, int columns) Creates a text area with the initial text and the number of rows and columns specified. Advanced Java Workshop 47 JTextArea Properties • • • • • • • • text editable columns lineWrap wrapStyleWord rows lineCount tabSize Advanced Java Workshop 48 JComboBox A combo box is a simple list of items from which the user can choose. It performs basically the same function as a list, but can get only one value. javax.swing.JComponent javax.swing.JComboBox +JComboBox() Creates a default empty combo box. +JComboBox(items: Object[]) Creates a combo box that contains the elements in the specified array. +addItem(item: Object): void Adds an item to the combo box. +getItemAt(index: int): Object Returns the item at the specified index. +getItemCount(): int Returns the number of items in the combo box. +getSelectedIndex(): int Returns the index of the selected item. +setSelectedIndex(index: int): void Sets the selected index in the combo box. +getSelectedItem(): Object Returns the selected item. +setSelectedItem(item: Object): void Sets the selected item in the combo box. +removeItem(anObject: Object): void Removes an item from the item list. Removes the item at the specified index in the combo box. +removeItemAt(anIndex: int): void +removeAllItems(): void Removes all items in the combo box. Advanced Java Workshop 49 JComboBox Methods To add an item to a JComboBox jcbo, use jcbo.addItem(Object item) To get an item from JComboBox jcbo, use jcbo.getItem() To get the index of an item, use jcbo.getItemIndex() Advanced Java Workshop 50 JList • This shows a list of items and allows a single selection or multiple selections • The “model” is the data that is to be displayed • The “view” is how you see that data • The “controller” mediates between the model and the view • You can’t add items to a JLIst; you add them to the model and they show up in the view Advanced Java Workshop 51 JList • The JList does not scroll. If you want it to, you must place it in a JScrollPane Advanced Java Workshop 52 Event-Driven Programming • GUI programs (and Android apps) must be able to respond to events • The obvious events are button clicks, keystrokes, etc. • There are many others, including every mouse motion • In Android, there are touch-screen events and sensor events, as well Advanced Java Workshop 53 JButton • JButton provides a simple button. It can have text, an icon, or both javax.swing.AbstractButton javax.swing.JButton +JButton() Creates a default button with no text and icon. +JButton(icon: javax.swing.Icon) Creates a button with an icon. +JButton(text: String) Creates a button with text. +JButton(text: String, icon: Icon) Creates a button with text and an icon. Advanced Java Workshop 54 JButton Constructors The following are JButton constructors: JButton() JButton(String text) JButton(String text, Icon icon) JButton(Icon icon) Advanced Java Workshop 55 JButton Properties • • • • • • • • text icon mnemonic horizontalAlignment verticalAlignment horizontalTextPosition verticalTextPosition iconTextGap Advanced Java Workshop 56 JButton Events • To respond to button clicks, add an event handler: JButton jbt = new Jbutton(“Press”); Jbt.addActionListener(new ActionListener(){ Public void actionPerformed(ActionEvent e){ // Do something here. } }); Advanced Java Workshop 57 JComboBox State Change Jcbo.AddItemListener(new cboStateChanged()); Class cboStateChanged implements ItemListener { public void itemStateChanged(ItemEvent e) { // Make sure the source is a combo box if (e.getSource() instanceof JComboBox) String s = (String)e.getItem(); } } Advanced Java Workshop 58 Swing Exercise • Write a program that displays three labels and three text fields, a JList, and has two buttons: Save and Cancel. • The program should accept data into the text fields, and display it in the JList when you press the Save button. Advanced Java Workshop 59 Text I/O • You can use the Scanner object to read text files. • This requires two objects: File and Scanner, per the following code: Scanner fRead = null; File fInput = null; fInput = new File(“Filename”); fRead = new Scanner(fInput); Advanced Java Workshop 60 Text I/O • The Scanner object has various methods: • nextLine() is probably the most useful. It reads a line of text up to the newline character. • nextInt() reads an integer up to the next nondigit. • nextDouble() reads a double Advanced Java Workshop 61 Text I/O • You can write text to a file with the PrintWriter class File fOut = new File(“File.txt”); PrintWriter pw = new PrintWriter(fOut); pw.writeLine(“This will be written”); Advanced Java Workshop 62 Binary I/O • Not all data is text • You may need to write code to deal with raw data, such as various data structures • Such data is not human-readable • For example, Java source code is text, but .class files are binary • Serialization is good too, but sometimes not sufficient Advanced Java Workshop 63 Binary I/O • When you write 65535 to a text file, Java converts this binary number to a sequence of characters and writes 10 bytes. (Unicode requires 2 bytes per character.) • When you write 65535 to a binary file, there is no conversion to characters. Exactly 4 bytes are written. Advanced Java Workshop 64 Binary I/O • A File object encapsulates the properties of a file or a path, but does not contain the methods for reading/writing data from/to a file. In order to perform I/O, you need to create objects using appropriate Java I/O classes. Advanced Java Workshop 65 Binary I/O Classes FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream Object OutputStream FileOutputStream BufferedOutputStream FilterOutputStream DataOutputStream ObjectOutputStream PrintStream Advanced Java Workshop 66 InputStream java.io.InputStream +read(): int Reads the next byte of data from the input stream. The value byte is returned as an int value in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value –1 is returned. +read(b: byte[]): int Reads up to b.length bytes into array b from the input stream and returns the actual number of bytes read. Returns -1 at the end of the stream. +read(b: byte[], off: int, len: int): int Reads bytes from the input stream and stores into b[off], b[off+1], …, b[off+len-1]. The actual number of bytes read is returned. Returns -1 at the end of the stream. +available(): int Returns the number of bytes that can be read from the input stream. +close(): void Closes this input stream and releases any system resources associated with the stream. +skip(n: long): long Skips over and discards n bytes of data from this input stream. The actual number of bytes skipped is returned. +markSupported(): boolean Tests if this input stream supports the mark and reset methods. +mark(readlimit: int): void Marks the current position in this input stream. +reset(): void Repositions this stream to the position at the time the mark method was last called on this input stream. Advanced Java Workshop 67 OutputStream The value is a byte as an int type. java.io.OutputStream +write(int b): void Writes the specified byte to this output stream. The parameter b is an int value. (byte)b is written to the output stream. +write(b: byte[]): void Writes all the bytes in array b to the output stream. +write(b: byte[], off: int, Writes b[off], b[off+1], …, b[off+len-1] into the output stream. len: int): void +close(): void Closes this input stream and releases any system resources associated with the stream. +flush(): void Flushes this output stream and forces any buffered output bytes to be written out. Advanced Java Workshop 68 RandomAccessFile • This is probably the most useful class • All of the streams you have used so far are known as read-only or write-only streams. The external files of these streams are sequential files that cannot be updated without creating a new file. It is often necessary to modify files or to insert new records into files. Java provides the RandomAccessFile class to allow a file to be read from and write to at random locations. Advanced Java Workshop 69 DataInput DataInput java.io.RandomAccessFile +RandomAccessFile(file: File, mode: String) Creates a RandomAccessFile stream with the specified File object and mode. +RandomAccessFile(name: String, mode: String) Creates a RandomAccessFile stream with the specified file name string and mode. +close(): void Closes the stream and releases the resource associated with the stream. +getFilePointer(): long Returns the offset, in bytes, from the beginning of the file to where the next read or write occurs. +length(): long Returns the length of this file. +read(): int Reads a byte of data from this file and returns –1 an the end of stream. +read(b: byte[]): int Reads up to b.length bytes of data from this file into an array of bytes. +read(b: byte[], off: int, len: int) : int Reads up to len bytes of data from this file into an array of bytes. +seek(long pos): void Sets the offset (in bytes specified in pos) from the beginning of the stream to where the next read or write occurs. +setLength(newLength: long): void Sets a new length of this file. +skipBytes(int n): int Skips over n bytes of input discarding the skipped bytes. +write(b: byte[]): void +write(byte b[], int off, int len) Writes b.length bytes from the specified byte array to this file, starting at the current file pointer. +write(b: byte[], off: int, len: int): void Writes len bytes from the specified byte array starting at offset off to this file. Advanced Java Workshop 70 DataInputStream/DataOutputStream • DataInputStream reads bytes from the stream and converts them into appropriate primitive type values or strings. • DataOutputStream converts primitive type values or strings into bytes and output the bytes to the stream. Advanced Java Workshop 71 DataInputStream InputStream FilterInputStream DataInputStream +DataInputStream( in: InputStream) java.io.DataInput +readBoolean(): boolean Reads a Boolean from the input stream. +readByte(): byte Reads a byte from the input stream. +readChar(): char Reads a character from the input stream. +readFloat(): float Reads a float from the input stream. +readDouble(): float Reads a double from the input stream. +readInt(): int Reads an int from the input stream. +readLong(): long Reads a long from the input stream. +readShort(): short Reads a short from the input stream. +readLine(): String Reads a line of characters from input. +readUTF(): String Reads a string in UTF format. Advanced Java Workshop 72 DataOutputStream OutputStream FilterOutputStream DataOutputStream +DataOutputStream( out: OutputStream) java.io.DataOutput +writeBoolean(b: Boolean): void Writes a Boolean to the output stream. +writeByte(v: int): void Writes to the output stream the eight low-order bits of the argument v. +writeBytes(s: String): void Writes the lower byte of the characters in a string to the output stream. +writeChar(c: char): void Writes a character (composed of two bytes) to the output stream. +writeChars(s: String): void Writes every character in the string s, to the output stream, in order, two bytes per character. +writeFloat(v: float): void Writes a float value to the output stream. +writeDouble(v: float): void Writes a double value to the output stream. +writeInt(v: int): void Writes an int value to the output stream. +writeLong(v: long): void Writes a long value to the output stream. +writeShort(v: short): void Writes a short value to the output stream. +writeUTF(s: String): void Writes two bytes of length information to the output stream, followed by the UTF representation of every character in the string s. Advanced Java Workshop 73 Characters and Strings in Binary I/O • A Unicode consists of two bytes. The writeChar(char c) method writes the Unicode of character c to the output. The writeChars(String s) method writes the Unicode for each character in the string s to the output. Advanced Java Workshop 74 What is UTF-8? • UTF-8 is a coding scheme that allows systems to operate with both ASCII and Unicode efficiently. Most operating systems use ASCII. Java uses Unicode. The ASCII character set is a subset of the Unicode character set. Since most applications need only the ASCII character set, it is a waste to represent an 8-bit ASCII character as a 16-bit Unicode character. The UTF-8 is an alternative scheme that stores a character using 1, 2, or 3 bytes. ASCII values (less than 0x7F) are coded in one byte. Unicode values less than 0x7FF are coded in two bytes. Other Unicode values are coded in three bytes. Advanced Java Workshop 75 Order and Format • CAUTION: You have to read the data in the same order and same format in which they are stored. For example, if names are written in UTF-8 using writeUTF, you must read names using readUTF. Advanced Java Workshop 76 Checking End of File • TIP: If you keep reading data at the end of a stream, an EOFException would occur. So how do you check the end of a file? You can use input.available() to check it. input.available() == 0 indicates that it is the end of a file. Advanced Java Workshop 77 File Pointer • The File Pointer is the position in the file where the next read or write will occur • When you open the file, this is set to zero • It is incremented by reading or writing • For example, if you read an int, the file pointer moves forward by 4 bytes Advanced Java Workshop 78 RandomAccessFile Methods • Many methods in RandomAccessFile are the same as those in DataInputStream and DataOutputStream. For example, readInt(), readLong(), writeDouble(), readLine(), writeInt(), and writeLong() can be used in data input stream or data output stream as well as in RandomAccessFile streams. Advanced Java Workshop 79 RandomAccessFile Methods • void seek(long pos) throws IOException; Sets the offset from the beginning of the RandomAccessFile stream to where the next read or write occurs. • long getFilePointer() IOException; Returns the current offset, in bytes, from the beginning of the file to where the next read or write occurs. Advanced Java Workshop 80 RandomAccessFile Methods • long length()throws IOException Returns the length of the file. • final void writeChar(int v) throws IOException Writes a character to the file as a two-byte Unicode, with the high byte written first. • final void writeChars(String s) throws IOException Writes a string to the file as a sequence of characters. Advanced Java Workshop 81 RandomAccessFile Constructor RandomAccessFile raf = new RandomAccessFile("test.dat", "rw"); //allows read and write RandomAccessFile raf = new RandomAccessFile("test.dat","r"); //read only Advanced Java Workshop 82 Random Access File Exercise • Write a program that, upon initialization, writes the integers 1-100 into the first 400 bytes of a file. It should then write 100 fourcharacter sequences from A001 through A100 into the next 400 bytes. • The program should then ask the user for a number from 1-100 and read the corresponding four-character sequence. The program terminates when the user enters 0. Advanced Java Workshop 83 Multithreading • Your program can have multiple threads running at the same time. They can run on the same CPU and time-slice, or run on different CPUs. • Threads must be careful not to interfere with each other. • See Edsger Dijkstra, “Cooperating Sequential Processes” Advanced Java Workshop 84 Creating Tasks and Threads java.lang.Runnable TaskClass // Custom task class public class TaskClass implements Runnable { ... public TaskClass(...) { ... } // Client class public class Client { ... public void someMethod() { ... // Create an instance of TaskClass TaskClass task = new TaskClass(...); // Create a thread Thread thread = new Thread(task); // Implement the run method in Runnable public void run() { // Tell system how to run custom thread ... } ... } // Start a thread thread.start(); ... } ... } Advanced Java Workshop 85 Multithreading • In the previous example, the Run method in the program fragment on the left is started by the thread.start() function on the right. • The function on the right that started the thread continues execution after the thread.start() call Advanced Java Workshop 86 The Thread Class «interface» java.lang.Runnable java.lang.Thread +Thread() Creates a default thread. +Thread(task: Runnable) Creates a thread for a specified task. +start(): void Starts the thread that causes the run() method to be invoked by the JVM. +isAlive(): boolean Tests whether the thread is currently running. +setPriority(p: int): void Sets priority p (ranging from 1 to 10) for this thread. +join(): void Waits for this thread to finish. +sleep(millis: long): void Puts the runnable object to sleep for a specified time in milliseconds. +yield(): void Causes this thread to temporarily pause and allow other threads to execute. +interrupt(): void Interrupts this thread. Advanced Java Workshop 87 The Static yield() Method You can use the yield() method to temporarily release time for other threads. For example, suppose you modify the code in Lines 53-57 in TaskThreadDemo.java as follows: public void run() { for (int i = 1; i <= lastNum; i++) { System.out.print(" " + i); Thread.yield(); } } Every time a number is printed, the print100 thread is yielded. So, the numbers are printed after the characters. Advanced Java Workshop 88 The Static sleep(milliseconds) Method The sleep(long mills) method puts the thread to sleep for the specified time in milliseconds. For example, suppose you modify the code in Lines 53-57 in TaskThreadDemo.java as follows: public void run() { for (int i = 1; i <= lastNum; i++) { System.out.print(" " + i); try { if (i >= 50) Thread.sleep(1); } catch (InterruptedException ex) { } } } Every time a number (>= 50) is printed, the print100 thread is put to sleep for 1 millisecond. Advanced Java Workshop 89 The join() Method You can use the join() method to force one thread to wait for another thread to finish. For example, suppose you modify the code in Lines 53-57 in TaskThreadDemo.java as follows: Thread public void run() { print100 Thread thread4 = new Thread( new PrintChar('c', 40)); -char token thread4.start(); try { +getToken for (int i = 1; i <= lastNum; i++) { printA.join() +setToken System.out.print(" " + i); +paintCompo Wait for printA -char if (i == 50) thread4.join(); net token to finish +mouseClicke } +getToken d } +getToken +setToken catch (InterruptedException ex) { +setToken +paintCompone } t +paintComponet } +mouseClicked Thread printA -char token +getToken +setToken +paintCompo net +mouseClicke d printA finished -char token The numbers after 50 are printed after thread printA is finished. Advanced Java Workshop 90 isAlive(), interrupt(), and isInterrupted() • The isAlive() method is used to find out the state of a thread. It returns true if a thread is in the Ready, Blocked, or Running state; it returns false if a thread is new and has not started or if it is finished. • The interrupt() method interrupts a thread in the following way: If a thread is currently in the Ready or Running state, its interrupted flag is set; if a thread is currently blocked, it is awakened and enters the Ready state, and an java.io.InterruptedException is thrown. • The isInterrupted() method tests whether the thread is interrupted Advanced Java Workshop 91 GUI Event Dispatcher Thread • GUI event handling and painting code executes in a single thread, called the event dispatcher thread. This ensures that each event handler finishes executing before the next one executes and the painting isn’t interrupted by events. Advanced Java Workshop 92 Thread Synchronization A shared resource may be corrupted if it is accessed simultaneously by multiple threads. For example, two unsynchronized threads accessing the same bank account may cause conflict. Step balance thread[i] thread[j] 1 2 3 4 0 0 1 1 newBalance = bank.getBalance() + 1; newBalance = bank.getBalance() + 1; bank.setBalance(newBalance); bank.setBalance(newBalance); Advanced Java Workshop 93 The synchronized keyword To avoid race conditions, more than one thread must be prevented from simultaneously entering certain part of the program, known as critical section. The critical section in the program is the entire deposit method. You can use the synchronized keyword to synchronize the method so that only one thread can access the method at a time. There are several ways to correct the problem. One approach is to make Account thread-safe by adding the synchronized keyword in the deposit method in Line 45 as follows: public synchronized void deposit(double amount) Advanced Java Workshop 94 Deadlock Sometimes two or more threads need to acquire the locks on several shared objects. This could cause deadlock, in which each thread has the lock on one of the objects and is waiting for the lock on the other object. Consider the scenario with two threads and two objects, as shown in Figure 29.15. Thread 1 acquired a lock on object1 and Thread 2 acquired a lock on object2. Now Thread 1 is waiting for the lock on object2 and Thread 2 for the lock on object1. The two threads wait for each other to release the in order to get the lock, and neither can continue to run. Step Thread 2 Thread 1 1 2 3 4 5 6 synchronized (object1) { synchronized (object2) { // do something here // do something here synchronized (object2) { synchronized (object1) { // do something here } // do something here } } Wait for Thread 2 to release the lock on object2 } Wait for Thread 1 to release the lock on object1 Advanced Java Workshop 95