Threads

A Simple Clock Applet

import java.awt.*;
import java.applet.*;
import java.util.*;

public class Clock0 extends Applet {
	public void paint(Graphics g) {
		String display = new Date() + "";
		FontMetrics fm = g.getFontMetrics();
		int stringWidth = fm.stringWidth(display);
		int screenWidth = getWidth();
		g.drawString(display, (screenWidth - stringWidth)/2, 100);
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		}
		
		repaint();
	}
}

A Related Applet: A Stopwatch

import java.util.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.*;

public class Clock1 extends Applet implements ActionListener {
	public void init() {
		setLayout(new FlowLayout(FlowLayout.CENTER));

		clock = new Label(simpleDateFormat.format(new Date(0)));
		add(clock);

		b = new Button("Start");
		add(b);
		b.addActionListener(this);
	}

	public void actionPerformed(ActionEvent e) {
		paused = !paused;
			if (!paused) {
			b.setLabel("Pause");
			if (firstTime) {
				firstTime = false;
				startClock();
			}
		}
		else
			b.setLabel("Resume");
	}

	void startClock() {
		Date startDate = new Date();
		
		while (true) {
			if (!paused) {
				Date duration = new Date(new Date().getTime() - startDate.getTime());
				clock.setText(simpleDateFormat.format(duration));
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
	}


	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");
	boolean paused = true;
	Button b;
	Label clock;
	boolean firstTime = true;
}

Threads

A Java application may have more than one thread of execution, or thread.

Creating a Running a Thread

Either:

Subclassing Thread

Fixing the Stopwatch

class Diag {
	static void threadPrint(String what) {
		System.err.println(what + ": " + Thread.currentThread().getName());
	}
}
Here's the Applet

import java.util.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.*;

public class Clock2 extends Applet implements ActionListener {
	public void init() {
		Diag.threadPrint("init");

		setLayout(new FlowLayout(FlowLayout.CENTER));
		Label clock = new Label(simpleDateFormat.format(new Date(0)));
		add(clock);

		b = new Button("Pause");
		b.setForeground(Color.red);
		add(b);
		b.addActionListener(this);

		clockThread = new Clock2Thread(clock);
		clockThread.start();
	}

	public void actionPerformed(ActionEvent e) {
		Diag.threadPrint("actionPerformed");
		boolean paused = clockThread.togglePaused();
		if (!paused) {
			b.setForeground(Color.red);
			b.setLabel("Pause");
		}
		else {
			b.setForeground(DARK_GREEN);
			b.setLabel("Resume");
		}
	}


	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");
	static final Color DARK_GREEN = new Color(0, 100, 0);
	Button b;
	Clock2Thread clockThread;
}

... and here's the thread ...

import java.awt.*;
import java.util.*;
import java.text.*;

class Clock2Thread extends Thread {
	Clock2Thread(Label clock) {this.clock = clock;}

	boolean togglePaused() {
		Diag.threadPrint("togglePaused");	
		paused = !paused;
		return paused;
	}

	public void run() {
		Diag.threadPrint("run");
		Date startDate = new Date();
		int count = 0;
		while (true) {
			if (!paused) {
				Date duration = new Date(new Date().getTime() - startDate.getTime());
				clock.setText(simpleDateFormat.format(duration));
				count++;
				if (count > 10) {
					Diag.threadPrint("tick");
					count = 0;
				}
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}
	}

	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");
	boolean paused = false;
	Label clock;
}

Why Threads?

Applications of Threads

#1 - A Word Processor #2 - A Threaded Application: A Web Server

#3 - Inputting, Processing and Outputting Blocks of Data

Cooperating (Non-preemptive) Threads

Preemptive Threads