Java——多线程
❀进程:
是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间)
❀线程:
- 线程是轻量级的进程
- 县城没有独立的地址空间(内存空间)
- 线程是由进程创建的(寄生在进程中)
- 一个进程可以拥有多个线程——多线程编程
- 线程的五种状态:新建状态new、就绪状态Runnable、运行状态Running、阻塞状态Blocking、死亡状态Dead
❀多线程:
就是程序同时完成多件事情,Java语言提供了并发机制,程序员可以在程序中执行多个线程,每一个线程完成一个功能,并与其他线程并发执行,这种机制被称为多线程。
❀实现线程的两种方式:
1、继承Thread类,并重写run函数
案例01:创建ThreadTest类,实现从10到1的逐个输出。
1 public class ThreadTest extends Thread{
2 private int count = 10;
3 public void run() {
4 while(true){
5 System.out.println(count+"");
6 if(--count==0){
7 return;
8 }
9 }
10 }
11 public static void main(String[] args) {
12 new ThreadTest().start();
13 }
14 }
完成线程正真功能的代码放在run()方法中,在main 方法中,执行线程需要调用Thread类中的start方法,start方法调用被覆盖的run()方法,如果不调用start()方法,线程永远都不会启动,在主方法没有调用start方法之前,Thread对象只是一个实例,而不是一个真正的线程。执行结果如下:
2、实现Runnable接口,并重写run函数
如果程序员要实现其他类,还要使当前类实现多线程,可以通过Runnable接口来实现,使用Runnable接口启动新线程的步骤如下:
- 建立Runnable对象
- 使用参数为Runnable对象的构造方法创建Thread实例
- 调用start()方法启动线程
案例02:创建Demo01类,实现每隔一秒输出一个“heloworld”,输出10次停止运行。
1 public class Demo01 {
2
3 public static void main(String[] args) {
4 //启动线程
5 Dog dog=new Dog();
6 Thread t=new Thread(dog);
7 t.start();
8 }
9
10 }
11 class Dog implements Runnable{
12 int times=0;
13 public void run(){
14 while(true){
15 try {
16 Thread.sleep(1000); //休眠1秒,这里用1000毫秒表示
17 } catch (Exception e) {
18 e.printStackTrace();
19 }
20 times++;
21 System.out.println("hello world"+" "+times);
22 if(times==10){
23 break;
24 }
25 }
26 }
27 }
运行结果:
❀sleep()方法:
这是一种能控制线程行为的方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位,通常是在run()方法的循环中被使用。
案例03:创建SleepThreadTest类,该类继承了JFrame类,实现在窗体中自动❀画线的功能,并设置线段的颜色,颜色由Random()函数随机产生。
1 package sleepmethod_01;
2 import java.awt.*;
3 import java.util.Random;
4 import javax.swing.*;
5
6 @SuppressWarnings("serial")
7 public class SleepMethodTest extends JFrame{
8 private Thread t;
9 //定义颜色数组
10 private static Color[] color={Color.BLACK,Color.blue,Color.CYAN,Color.GREEN,
11 Color.ORANGE,Color.YELLOW,Color.RED,Color.PINK,Color.LIGHT_GRAY};
12 private static final Random rand = new Random(); //创建随机对象
13 private static Color getC(){ //获取随机颜色值的方法
14 return color[rand.nextInt(color.length)];
15 }
16 public SleepMethodTest(){
17 t = new Thread(new Runnable(){ //创建匿名线程对象
18 int x = 30; //定义初始坐标
19 int y = 50;
20 public void run(){ //覆盖无线接口方法
21 while(true){ //无限循环
22 try {
23 Thread.sleep(100); //线程休眠0.1秒
24 } catch (Exception e) {
25 e.getStackTrace();
26 }
27 Graphics graphics = getGraphics();
28 graphics.setColor(getC()); //设置绘图颜色
29 graphics.drawLine(x, y, 100, y++);//绘制直线并递增垂直坐标
30 if(y>=80){
31 y=50;
32 }
33 }
34 }
35 });
36 t.start(); //启动线程
37 }
38
39 public static void main(String[] args) {
40 init(new SleepMethodTest(),100,100);
41
42 }
43 //初始化程序界面方法
44 public static void init(JFrame frame,int width,int height){
45 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
46 frame.setSize(width,height);
47 frame.setVisible(true);
48 }
49
50 }
03例中,由于sleep()方法执行时有可能抛出 InterruptException异常,所以将sleep()方法的调用放在try/catch块中。
运行结果:
❀继承Thread vs 实现Runnable:
- 尽可能使用实现Runnable接口的方式来创建线程
- 在使用Thread的时候只需要new一个实例出来,调用start()方法即可以启动一个线程:
Thread test = new Thread();
test.start();
3.在使用Runnable的时候需要先new一个实现Runnable的实例,之后用thread调用:
Test implements Runnable
Test t = new Test();
Thread test = new Thread(t);
test.start();