创建线程程序
Java语句的一个复杂特性是,能够使用线程编写具有多任务功能的程序,Java的该功能是通过称为线程的对象类实现的。
1、线程
线程是一种组织程序的方式,使其能够同时做多项工作。需要同时执行的每项任务都运行在自己的线程中,这通常是通过将每项任务作为独立的类来实现的。
线程用Thread类和Runnable接口表示,它的一种最简单的用途是降低程序完成工作的速度。
1)、创建线程
可作为线程运行的Java类常被称为“线程化类”。如果将耗时的任务放在独立的线程中,程序的其他部分运行起来将更快,这通常用于防止任务降低程序的图形用户界面的响应速度。
例如编写了一个从磁盘加载股价数据并生成统计数据的程序,最耗时的任务是从磁盘加载数据。如果不在应用程序中使用线程,加载数据时程序的界面响应将很慢。这可能让用户失去耐心。
有两种方法可将任务放在线程中:
>将任务放在实现了Runnable接口的类中;
>将任务放在Thread的子类中;
当实现了Runnable接口后,其类必须包含run()方法,因为run()方法应完成线程要完成的任务。
当线程应用程序运行时,不会自动执行run()方法中的语句。在Java中可以启动和终止线程,要运行线程,必须做下面两项工作:
>通过调用构造函数Thread创建线程化类的对象;
>通过调用start()方法启动线程;
>通过thread = null来终止线程;
构造函数Thread接受一个参数——包含线程的run()方法的对象。通常使用this作为参数,this表明当前类包含的run()方法。
下面来看一个例子:
package javaapplication1;
import java.awt.BorderLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class test01 extends JFrame implements Runnable , ActionListener{
Thread go;
JLabel howManyLabel;
JTextField howMany;
JButton display;
JTextArea primes;
public test01() throws HeadlessException {
super("寻找素数");
setSize(400 , 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout bord = new BorderLayout();
setLayout(bord);
howManyLabel = new JLabel("数量:");
howMany = new JTextField("400" , 10);
display = new JButton("显示素数");
primes = new JTextArea(8 , 40);
display.addActionListener(this);
JPanel topPanel = new JPanel();
topPanel.add(howManyLabel);
topPanel.add(howMany);
topPanel.add(display);
add(topPanel , BorderLayout.NORTH);
primes.setLineWrap(true);
JScrollPane textPane = new JScrollPane(primes);
add(textPane , BorderLayout.CENTER);
setVisible(true);
}
@Override
public void run() {
int quantity = Integer.parseInt(howMany.getText());
int numPrimes = 0;
//最小素数
int candidate = 2;
primes.append("Fisrt:" + quantity + " primes:");
while (numPrimes < quantity) {
if (IsPrime(candidate)) {
primes.append(candidate + " ");
numPrimes++;
}
candidate++;
}
}
public static boolean IsPrime(int checkNumber)
{
double root = Math.sqrt(checkNumber);
for (int i = 2; i < root; i++) {
if (checkNumber % i == 0) {
return false;
}
}
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
display.setEnabled(false);
if (go == null) {
go = new Thread(this);
go.start();
}
}
public static void main(String[] args)
{
test01 test = new test01();
}
}
此例子计算400以内的素数并在文本框中列出,显示结果如图:
2、创建线程
下面的例子是创建一个能够在网页中运行的多线程应用程序,在程序中你将学会如何开启和终止线程,以及如何使用代码打开浏览器。
test01.java:
import java.applet.AppletContext;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.JApplet;
public class test01 extends JApplet implements Runnable , ActionListener{
String[] pageTitle = new String[6];
URL[] PageLink = new URL[6];
Color butterscotch = new Color(255 , 204, 158);
int current = 0;
Thread runner;
@Override
public void init() {
pageTitle = new String[]{
"百度" ,
"搜狐" ,
"谷歌" ,
"网易" ,
"腾讯" ,
"淘宝"};
PageLink[0] = getURL("http://www.baidu.com");
PageLink[1] = getURL("http://www.sohu.com/");
PageLink[2] = getURL("http://www.google.com");
PageLink[3] = getURL("http://www.163.com");
PageLink[4] = getURL("http://www.qq.com");
PageLink[5] = getURL("http://www.taobao.com");
Button goButton = new Button("Go");
goButton.addActionListener(this);
FlowLayout flow = new FlowLayout();
setLayout(flow);
add(goButton);
}
URL getURL(String urlText)
{
URL pageURL = null;
try {
pageURL = new URL(getDocumentBase() , urlText);
} catch (Exception e) {
e.printStackTrace();
}
return pageURL;
}
@Override
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D)g;
g2D.setColor(butterscotch);
g2D.fillRect(0, 0, getSize().width, getSize().height);
g2D.setColor(Color.black);
g2D.drawString(pageTitle[current], 5, 60);
g2D.drawString("" + PageLink[current], 5, 80);
}
@Override
public void start() {
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
@Override
public void run() {
Thread thisThread = Thread.currentThread();
while (runner == thisThread) {
current++;
if (current > 5) {
current = 0;
}
repaint();
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void stop() {
if (runner != null) {
runner = null;
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (runner != null) {
runner = null;
}
AppletContext browser = getAppletContext();
if (PageLink[current] != null) {
browser.showDocument(PageLink[current]);
}
}
}
WeightScale.html:
<applet code="test01.class" codebase="..\\..\\build\\classes"
height="100" width="300">
<param name="person" value="konishiki"/>
<param name="weight" value="605"/>
</applet>
效果图如下: