Download Thread Scheduling can be either preemptive or time

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
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