任何继承了Thread的类都可以创立单独的线程
public class ThreadDemo1 extends Thread {
private String name;
private int count;
private int delay;
public static void main(String arg[]) {
ThreadDemo1 one = new ThreadDemo1("one",1000,2);
one.start();//发起一个线程
ThreadDemo1 two = new ThreadDemo1("two",2000,5);
two.start();//发起第二个线程
}
ThreadDemo1(String nameString,int countStart,int seconds) {
name = nameString;
count = countStart;
delay = seconds * 1000;
}
public void run() { //线程运行时执行的代码
while(true) {
try {
System.out.println(name + ": " + count++);
Thread.sleep(delay);
} catch(InterruptedException e) {
return;
}
}
}
}
发一个弹球的例程,在BounceBallCanvas类继承了Canvas,那么就必须重新创建一个类BounceBallThread去继承Thread
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.Canvas;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class ThreadDemo2 extends JFrame {
public static void main(String arg[]) {
new ThreadDemo2();
}
public ThreadDemo2() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{ System.exit(0); } } );
Container container = getContentPane();
BounceBallCanvas canvas = new BounceBallCanvas();
container.add(canvas);
pack();
BounceBallThread bbt = new BounceBallThread(canvas);
bbt.start();
setLocation(250,100);
setVisible(true);
}
}
class BounceBallThread extends Thread {
BounceBallCanvas canvas;
BounceBallThread(BounceBallCanvas bbc) {
canvas = bbc;
}
public void run() {
while(true) {
try {
sleep(33);
canvas.repaint();
} catch(Exception e) {
System.out.println(e.getStackTrace());
}
}
}
}
class BounceBallCanvas extends Canvas {
private double y;
private double x;
private final static int diameter = 10;
private final static double gravity = 0.3;
private double velocity;
private Rectangle rect;
private int width;
private int height;
private Image image = null;
private boolean running;
private Thread looper;
private int bounceCount;
BounceBallCanvas() {
rect = null;
setSize(100,300);
running = false;
height = 0;
width = 0;
}
public void update(Graphics g) {
rect = getBounds(rect);
if((height != rect.height) || (rect.width != width)) {
height = rect.height;
width = rect.width;
velocity = 0.0;
bounceCount = 0;
x = width / 2;
y = 0;
image = createImage(rect.width,rect.height);
}
if(velocity > 0.0) {
if(((int)(y) + diameter) > rect.height) {
velocity = -velocity;
velocity *= 0.95;
y = (double)(rect.height - diameter);
if(++bounceCount > 20) {
y = 0;
velocity = 0.0;
bounceCount = 0;
}
}
}
velocity += gravity;
y += velocity;
paint(image.getGraphics());
g.drawImage(image,0,0,this);
}
public void paint(Graphics g) {
if(rect == null)
return;
g.setColor(Color.white);
g.fillRect(0,0,rect.width,rect.height);
g.setColor(Color.black);
g.fillOval((int)x,(int)y,diameter,diameter);
}
}
在run()方法中可以使用Thread类的静态方法返回当前线程的引用,然后进行获取线程的名字等操作
Thread thread = Thread.currentThread();静态方法,
String name = thread.getName();
具体的请见Thread类。
值得注意的是
1.线程运行中对成员变量的操作和主线程对其的操作,操作的对象是同一个。而两个独立的线程则分别拥有数据空间。
2.若覆盖了start()方法,则要先调用super.start()方法,否则还是运行在主线程中运行run()方法。例如:
package org.bupt.test;
public class Machine extends Thread{
private int a=0;
private static int count =0;
public void start() {
super.start();//确保线程创建
System.out.println(currentThread().getName()+":第"+(++count)+"个线程启动"); //start()方法被覆盖后,就是由主线程执行这句话。
}
public void run() {
for (a = 0; a < 50; a++) {
System.out.println(currentThread().getName()+":"+a);
try {
sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Machine machine1=new Machine();
Machine machine2=new Machine();
machine1.start();
machine2.start();
}
}
3.一个线程只能被启动一次。