Java Lecture 8
[Previous Lecture]
[Lecture Index]
Intro to Threads
Threads
- have independent flows of control (execute different code "simultaneously")
- may share objects (same "address space")
- are represented by the
Thread class
Creating threads
- create a class with a
public void run()
- class must either
extend java.lang.Thread
or
implement java.lang.Runnable
- create a Thread object using this class
For example,
class MyThread extends Thread {
// ...
public void run() {
// ...
}
// ...
}
// ...
MyThread t = new MyThread();
or (the more flexible option)
class MyClass implements Runnable {
// ...
public void run() {
// ...
}
// ...
}
// ...
myClass = new MyClass();
// ...
Thread t = new Thread(myClass);
Once created, start the thread using
t.start();
(thread t starts executing the run() method).
PrintApplet.java
/*
* <applet code=PrintApplet width=400 height=200>
* </applet>
*/
import java.awt.*;
public class PrintApplet extends java.applet.Applet
{
private TextArea text;
private Thread t1, t2;
public void init() {
text = new TextArea(10, 40);
add(text);
t1 = new Thread(new PrintThread("A", 1000, text));
t2 = new Thread(new PrintThread(" B", 600, text));
t1.start();
t2.start();
}
}
class PrintThread implements Runnable {
private String name;
private int delay;
private TextArea ta;
public PrintThread(String name, int delay, TextArea ta)
{
this.name = name;
this.delay = delay;
this.ta = ta;
}
public void run() {
for (int i = 0; i < 10; i++) {
ta.append(name + ": " + i + "\n");
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}
ta.append(name + ": finished" + "\n");
}
}
Static Thread methods
Thread th = Thread.currentThread();
-
gets the
Thread object for the thread that
executes this call (the "current thread").
Thread.sleep(milliseconds);
-
puts the current thread to sleep for that length of time. (almost always
called in a
try block to catch the
InterruptedException.)
Thread.yield();
-
lets another thread run (if there is one that can run).
normal Thread methods
void start()
-
starts the thread running. The
run() method of the
Runnable attached to the Thread is called
in that thread.
void stop()
-
stops the thread immediately. The thread cannot be restarted.
more normal Thread methods
void suspend()
-
stops the thread from running, until a
resume() is
called.
void resume()
-
causes the thread to continue running from where it was suspended.
void setPriority(int prio)
-
changes the priority of the thread. Threads with a higher valued
priority run preferentially to lower priority threads.
int getPriority()
-
returns the priority of the thread.
void join()
-
causes the current thread to wait until this thread is
finished (either
run() returns or the thread is
stop()-ed).
Keeping your data safe
The synchronized keyword.
- synchronize a method
class SharedPoint {
int x, y;
public synchronized void set(Point n) {
x = n.x; y = n.y;
}
public synchronized Point get() {
return new Point(x, y);
}
}
- synchronize a block
SharedPoint s;
...
synchronized (s) {
Point n = s.get();
n.x += 10; n.y += 20;
s.set(n);
}
MovingImage.java
/*
* <applet code=MovingImage width=400 height=400>
* </applet>
*/
import java.awt.*;
import java.awt.event.*;
public class MovingImage extends java.applet.Applet implements Runnable
{
public void init() {
image = getImage(getCodeBase(), "image.gif");
getBuffer();
addMouseMotionListener(
new MouseMotionAdapter() {
public void mouseDragged(MouseEvent me) {
calcDelta(me.getX(), me.getY());
point = new Point(me.getX(), me.getY());
repaint();
}
}
);
}
public void start() {
if (mover == null) {
mover = new Thread(this);
mover.start();
}
}
public void stop() {
if (mover != null) {
mover.stop();
mover = null;
}
}
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
moveByDelta();
repaint();
}
}
private synchronized void calcDelta(int newX, int newY)
{
if (point != null) {
deltaX = newX - point.x;
deltaY = newY - point.y;
}
}
private synchronized void moveByDelta() {
if (point != null) {
int xNew = point.x + deltaX;
int yNew = point.y + deltaY;
if (xNew < 0) {
deltaX = -deltaX;
xNew = - xNew;
} else if (xNew > bufferSize.width) {
deltaX = -deltaX;
xNew -= xNew - bufferSize.width;
}
if (yNew < 0) {
deltaY = -deltaY;
yNew = -yNew;
} else if (yNew > bufferSize.height) {
deltaY = -deltaY;
yNew -= yNew - bufferSize.height;
}
point.x = xNew;
point.y = yNew;
}
}
public void update(Graphics g) {
updateBuffer();
paint(g);
}
public void paint(Graphics g) {
if (!getSize().equals(bufferSize))
getBuffer();
g.drawImage(bufferImage, 0, 0, this);
}
private void getBuffer() {
if (bufferImage != null) {
bufferImage.flush();
bufferImage = null;
}
bufferSize = getSize();
bufferImage = createImage(bufferSize.width, bufferSize.height);
updateBuffer();
}
private void updateBuffer() {
Graphics buffer = bufferImage.getGraphics();
buffer.clearRect(0, 0, bufferSize.width, bufferSize.height);
if (point != null)
buffer.drawImage(image, point.x, point.y, this);
}
private int deltaX, deltaY;
private Point point; // where to draw
private Image image; // what to draw
private Image bufferImage; // what to draw on
private Dimension bufferSize;
private Thread mover;
}
[Previous Lecture]
[Lecture Index]