概念
有很多工作是可以同时完成的,这种思想放在Java中被称为并发,并发完成每一件事被称为线程。
程序员可以在程序中执行多个线程,每一个线程完成一个功能//与其他线程并发执行,这种机制被称为多线程,并不算所有编程语言都支持多线程。
创建线程
继承Thread类和实现Runnable接口两种方法
继承Thread类
是Java.long包下的一个类,在这个类中实例化对象代表线程,程序员启动一个新线程需要建立一个实例。Thread类常用的两种构造方法如下:
public Thread():创建一个新的线程对象
public Thread(String threadName):创建一个名为threadName的线程对象
继承Thread类创建一个新的线程的语法如下:
public class ThreadTest extends Thread{
}
完成线程真实代码的功能放在run()方法,当继承Thread类后,就可以在该线程中覆盖run()方法,将实现线程功能的代码写入run()方法中,调用run()方法。
Thread对象需要一个任务来执行,任务是指线程在启动时执行的工作,这个代码写在了run()方法中,语法格式如下:
public void run(){
}
如果start()方法调用一个已经启动的线程,系统将抛出IllegalThreadStateException异常
例题20.1
实现Runnable接口
线程都是通过扩展 Thread 类来创建的,如果需要继承其他类(非 Thread类),而且还要使当前类实现多线程,那么可以通过 Runnable 接口来实现。实现 Runnable 接口的语法如下:
-
public class Thread extends Object implements Runnable{ }
操作线程的方法
操作线程有很多方法,这些方法可以使线程从某一种状态过波到另一种状态。
线程的休眠
一种能控制线程行为的方法是调用 seep()方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位。slep()方法的语法如下:
try{ Thread.sleep(2000); }catch(InterruptedException e){ e.printStackTrace(); } 上述代码会使线程在 2 秒之内不会进入就绪状态。 由于 sleep()方法的执行有可能抛InterrupledException 异常,所以将 sleep()方法的调用放在 try-catch 块中。
package lx; import java.awt.Color; import java.awt.Graphics; import java.util.Random; import javax.swing.JFrame; public class Demo20_3 extends JFrame { private static Color[]color= {//定义颜色数组 Color.BLACK,Color.BLUE,Color.CYAN,Color.GREEN,Color.ORANGE,Color.YELLOW ,Color.RED,Color.PINK,Color.LIGHT_GRAY }; private static final Random rand=new Random(); //创建随机对象 private static Color getC() {//获取随机颜色值的方法 return color[rand.nextInt(color.length)]; } public Demo20_3() { Thread t=new Thread(new Runnable() { //创建匿名线程对象 int x=70; //定义初始坐标 int y=50; public void run() { while(true) {//无限循环 try { Thread.sleep(100);//线程休眠0.1秒 }catch(InterruptedException e){ e.printStackTrace(); } Graphics g= getGraphics();//获取组件绘图上下文对象 g.setColor(getC());//设置绘图颜色 g.drawLine(x, y, 200, y++);//绘制直线并递增垂直坐标 if(y>=100) { y=50; } } } }); t.start();//启动线程 } public static void main(String[] args) { init(new Demo20_3(),300,100); } public static void init(JFrame f,int w,int h) {//初始化程序界面的方法 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(w, h); f.setVisible(true); } }
线程的加入
如果当前某程序为多线程程序,假如存在一个线程 A,现在需要插入线程 B,并要求线程 B 先执行完毕,然后再继续执行线程 A,此时可以使用 Thread 类中的 join()方法来完成。
例题20.4
package lx; import java.awt.BorderLayout; import javax.swing.*; public class Demo20_4 extends JFrame{ private Thread A;//定义两个线程 private Thread B; private JProgressBar Bar=new JProgressBar();//定义两个进度条组件 private JProgressBar Bar2=new JProgressBar(); public static void main(String[] args) { Demo20_4 Text=new Demo20_4(); Text.setVisible(true); } public Demo20_4() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(200,200,200,100); getContentPane().add(Bar,BorderLayout.NORTH);//将进度条设置在窗体最北面 getContentPane().add(Bar2,BorderLayout.SOUTH);//将进度条设置在窗体最南面 Bar.setStringPainted(true);//设置进度条显示数字字符 Bar2.setStringPainted(true); A=new Thread(new Runnable() {//使用匿名内部类形式初始化Thread实例 int c=0; public void run() {//重写润()方法 while(true) { Bar.setValue(c++);//设置进度条当前值 try { Thread.sleep(100);//让A线程休眠100毫秒 B.join();//让/B调用join()方法 if(c==30)//设置当A线程走到了30,B线程才启动 B.start();//启动B线程 }catch(InterruptedException e) { e.printStackTrace(); } } } }); A.start();//启动A线程 B=new Thread(new Runnable() { int c=0; public void run() { while(true) { Bar2.setValue(++c);//设置进度条当前值 try { Thread.sleep(100);//让B线程休眠100毫秒 }catch(InterruptedException e) { e.printStackTrace(); } if(c==100)//当c变量增长为100时 break; //跳出循环 } } }); } }