Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Acc680 Lect02 - Thread A thread--sometimes called an execution context or a lightweight process--is a single sequential flow of control within a program (Java Tutorial). Java uses threads to make JMV look like multiple machines running at the same time. Thread Scheduling can be either preemptive or time-sliced (aka round-robin). Garbage collection is run as a low priority thread, but could be promoted to high priority when the system is running out of memory. MIN_PRIORITY =1; MAX_PRIORITY =10; NORM_PRIORITY =5. In time-slicing, each thread is given a small piece of the CPU's time, and when that time expires, the thread must wait if there are other threads of equal or higher priority waiting for the CPU. Windows OS uses time-slicing. In Preemption, the currently running thread preempts all threads of equal priority. The CPU runs a thread to completion if no higher-priority thread is waiting. Threads of a priority equal to that of the currently running thread must wait. Only a higher-priority thread can preempt (or displace) the current thread. Solaris OS uses preemption. /** (Barnes, 2000) The frame object executes in a separate thread from the main method. */ import java.awt.*; import java.awt.event.*; public class FifthFrame extends Frame implements ActionListener, WindowListener { Button bh, bw; TextField tf; public FifthFrame() { setSize(300, 300); addWindowListener(this); bh = new Button("Hello"); bw = new Button("World!"); bh.addActionListener(this); bw.addActionListener(this); tf = new TextField(""); tf.setFont(new Font("Serif", Font.BOLD + Font.ITALIC, 30)); Panel pa = new Panel(); pa.add(bh); pa.add(bw); add(pa, BorderLayout.NORTH); add(tf, BorderLayout.CENTER); } public void actionPerformed (ActionEvent e) { if (e.getSource() == bh) tf.setText("Hello"); else tf.setText("World!"); } //closing window destroys the GUI thread, but not the main thread public void windowClosing (WindowEvent e) { Window w = e.getWindow(); w.setVisible(false); w.dispose(); //let OS reclaim resources used by window } public public public public public public void void void void void void windowOpened (WindowEvent e){} windowClosed (WindowEvent e){} windowIconified (WindowEvent e){} windowDeiconified (WindowEvent e){} windowActivated (WindowEvent e){} windowDeactivated (WindowEvent e){} public static void main (String [] args) { FifthFrame ff = new FifthFrame(); ff.setVisible(true); while (true) System.out.println(Math.random()); } } 1 Thread Construction Define a subclass of the Thread class and overrides the run() method. Call the start() method from instances of this subclass. public class SevenThreads { public static void main(String [] args) { CounterThread t1 = new CounterThread("ThreadOne "); CounterThread t2 = new CounterThread("ThreadTwo "); CounterThread t3 = new CounterThread("Threadthree "); CounterThread t4 = new CounterThread("ThreadFour "); CounterThread t5 = new CounterThread("ThreadFive "); CounterThread t6 = new CounterThread("ThreadSix "); CounterThread t7 = new CounterThread("ThreadSeven "); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start(); t7.start(); Define a new class that Implement the Runnable interface and overrides the run() method. Create an instance of this new class, and use it in the Thread() constructor to construct a Thread object. Call the start() method from this Thread object. public class SixThreads { public static void main(String [] args) { CounterRunnable cr = new CounterRunnable(); Thread t1 = new Thread(cr, "ThreadOne "); Thread t2 = new Thread(cr, "ThreadTwo "); Thread t3 = new Thread(cr, "Threadthree "); Thread t4 = new Thread(cr, "ThreadFour "); Thread t5 = new Thread(cr, "ThreadFive "); Thread t6 = new Thread(cr, "ThreadSix "); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start(); } } } } class CounterThread extends Thread { public CounterThread(String name) { super(name); } public void run() { for (int i = 0; i < 100; i++) System.out.println(this.getName() + i); } } C:\>java SevenThreads ..... ThreadSeven 93 ThreadFive 99 ThreadTwo 98 ThreadSix 99 ThreadFour 98 ThreadSeven 94 ThreadTwo 99 ThreadFour 99 ThreadSeven 95 ThreadSeven 96 ThreadSeven 97 ThreadSeven 98 ThreadSeven 99 ThreadOne 7 ThreadOne 8 ThreadOne 9 ThreadOne 10 ..... class CounterRunnable implements Runnable { public void run() { for (int i = 0; i < 100; i++) System.out.println(Thread.currentThread().getName() + i); } } C:\>java SixThreads ..... ThreadTwo 94 Threadthree 94 ThreadFive 94 ThreadFour 94 ThreadSix 94 ThreadOne 98 ThreadTwo 95 Threadthree 95 ThreadFive 95 ThreadFour 95 ThreadSix 95 ThreadOne 99 ThreadTwo 96 Threadthree 96 ThreadFive 96 ThreadFour 96 ThreadSix 96 ..... Life cycle of a Thread [start()] ready [assigned a CPU] running [sleep()] sleeping [sleep time expires] ready [start()] ready [assigned a CPU] running [wait()] waiting for a lock to some object [notify(), notifyAll()] ready [start()] ready [assigned a CPU] running [yield()] ready *cannot yield to lower priority thread! notify() awakens one arbitrary waiting thread. notifyAll() awakens all waiting threads. 2 run() vs. start() //Invoking the run() method on a Thread object causes only the main thread to run public class NoThread { public static void main(String [] args) { CounterRunnable cr = new CounterRunnable(); Thread t1 = new Thread(cr, "ThreadOne "); t1.run(); System.out.println("End of main()"); } } class CounterRunnable implements Runnable { public void run() { for (int i = 0; i < 10; i++) System.out.println(Thread.currentThread().getName() + i); } } %java NoThread main0 main1 main2 main3 main4 main5 main6 main7 main8 main9 End of main() //Calling the start() method from the Thread object registers the thread with the Thread Scheduler public class OneThread { public static void main(String [] args) { CounterRunnable cr = new CounterRunnable(); Thread t1 = new Thread(cr, "ThreadOne "); t1.start(); //a new thread is spawned at this point to be executed along the main thread System.out.println("End of main()"); } } class CounterRunnable implements Runnable { public void run() { for (int i = 0; i < 10; i++) System.out.println(Thread.currentThread().getName() + i); } } %java OneThread End of main() ThreadOne 0 ThreadOne 1 ThreadOne 2 ThreadOne 3 ThreadOne 4 ThreadOne 5 ThreadOne 6 ThreadOne 7 ThreadOne 8 ThreadOne 9 3 Socket (Client & Server) Programming client reads line from standard input, sends to server via socket server reads line from socket server converts line to uppercase, sends back to client client reads, prints modified line from socket 1. 2. 3. 4. import java.io.*; import java.net.*; class UpperClient { public static void main(String argv[]) throws Exception { String sentence; String modifiedSentence; BufferedReader inFromUser = //reader & writer handle character data new BufferedReader(new InputStreamReader(System.in)); //check /etc/services for available ports Socket clientSocket = new Socket("hostname", somePortNumber); DataOutputStream outToServer = //inputStream and outputStream handle byte data new DataOutputStream(clientSocket.getOutputStream()); //OutputStream cannot write strings BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); sentence = inFromUser.readLine(); outToServer.writeBytes(sentence + '\n'); modifiedSentence = inFromServer.readLine(); System.out.println("FROM SERVER: " + modifiedSentence); clientSocket.close(); } } import java.io.*; import java.net.*; class UpperServer { public static void main(String argv[]) throws Exception { String clientSentence, capitalizedSentence; //a ServerSocket wait for requests to reach server ServerSocket welcomeSocket = new ServerSocket(somePortNumber); while(true) { Socket connectionSocket = welcomeSocket.accept(); BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); clientSentence = inFromClient.readLine(); capitalizedSentence = clientSentence.toUpperCase() + '\n'; outToClient.writeBytes(capitalizedSentence); } } } 4 ACC680 HW1: TCP Socket Programming Due April 24, 2006 Refer to the 2005 Tax Rate Schedules available in IRS' web document of 1040 instructions (Section A, p. 77): http://www.irs.gov/pub/irs-pdf/i1040.pdf You are required to write the client and the server sides of a TCP-based tax calculator application. The client application will prompt the user for an income number to be forwarded to the server. The server will calculate the tax liability and send back the result to be displayed to the user. The user then may decide to quit or to start a new calculation. Use cayley.bus.albany.edu as the server. Pick a server port number (larger than 1023) for your application. Check the /etc/services file (or use the netstat -a command) on cayley to avoid using port numbers already assigned. Pick a second machine (such as a PC) as the client. Submit a typescript file in which you should cat the server and the client file (call them Stax.java and Ctax.java). Assume that the user first tries with two income levels of 30000 and 50000. He then quits the client but immediately reruns the client with income level of 60000. Leave the sever running throughout the testing. When testing is completed, quit the server with control-C. Capture and submit the client side display. 5