Java并发编程(一)——线程

本文介绍了Java中线程的实现方式,包括继承Thread类和实现Runnable接口。详细阐述了线程的生命周期,包括新建、就绪、运行、阻塞和死亡状态,并解析了线程状态的转换。此外,还提到了Thread类的常用API,如设置线程名、守护线程、线程优先级等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java并发编程(一)——线程

一,线程的实现方式

  Java中实现多线程有两种方式,如下:

1,继承java.lang.Thread类,重写run()方法; 
2,实现java.lang.Runnable接口,重写接口中的run()方法。

  这两种实现方式没有优劣,但由于Java中不允许多继承,所以使用第二种实现接口的方式更加灵活。
  另外需要注意的是实现了Runnable的类,就像其字面描述的意思一样,只是一个可运行的东西,最终也是要Thread类来启动它,它才能跑起来。这一点从源码上分析来看,只能说Runnable接口只是为了用来在不能多继承的情况下来实现多线程而设计的,最终线程的内容和启动还是Thread来实现的。
  代码如下:

    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t = new Thread();
            t.start();

            Thread t2 = new Thread(new Line());
            t2.start();
        }
    }
    class Line implements Runnable{

        @Override
        public void run() {
            System.out.println("Line Thread is running...");
        }
    }

  而更多的情况下,我们会采用匿名内部类来实现多线程:

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I'm a new Thread");
            }
        }).start();
    }

二,线程的生命周期

  线程的生命周期是指一个线程从创建到消亡的过程。

  • 新建状态(New)
      当用new操作符创建一个新的线程对象时,该线程处于创建状态。处于创建状态的线程只是一个空的线程对象,系统不为它分配资源。
    注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常。如下:
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("I'm a new Thread");
        }
    });
    t.start();
    t.start();//同一个(同id)线程不能同时启动两次

另,线程是不能clone的,因为线程id是不能重复的,会抛出CloneNotSupportedException异常,见源码:

    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
  • 就绪状态(Runnable)
      线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
  • 运行状态(Running)
      就绪状态的线程获取了CPU的使用权,执行程序代码的过程就处于运行态。
  • 阻塞状态(Blocked)
      阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (1)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
    (2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
    (3)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead)
      线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

三,线程状态的转换

1,线程生命周期图

这里写图片描述
这里写图片描述

2,线程状态的切换方式:

1)yield():yield的意思是让步,让出,就是暂时让出CPU的使用权,所以从Running变为了Runnable状态。
2)sleep():使线程睡眠一定的时间,由Running态变为Blocked态。
3)join():使当前线程(如主线程)挂起,直到调用join方法的线程执行完毕。
4)exit():在线程进入Running之前可以清空并退出该线程。
5)stop():强制线程退出,已废弃
6)suspend():挂起线程,由Running变为Blocked,和resume相对应,已废弃
7)resume():恢复线程,由Blocked变为Runnable,已废弃
8)interrupt():打断/中断线程。

四,Thread类的常用API

void setName(String name):为线程设置线程名;
  守护线程和用户线程的区别在于:守护线程依赖于创建它的线程,而用户线程则不依赖。举个简单的例子:如果在main线程中创建了一个守护线程,当main方法运行完毕之后,守护线程也会随着消亡。而用户线程则不会,用户线程会一直运行直到其运行完毕。在JVM中,像垃圾收集器线程就是守护线程。
void setDaemon(boolean on):设置是否是守护线程,是谁的守护线程?是当前线程的守护线程;需要在start方法调用之前使用;另,在Daemon线程中产生或新建的新线程默认也是Daemon的。

public class DaemonDemo {

    public static void main(String[] args) throws InterruptedException {
        TestThread test = new TestThread();
        // 如果不设置daemon,那么线程将输出10后才结束
        test.setDaemon(true);
        test.start();
        System.out.println("isDaemon = " + test.isDaemon());
        try {
            System.in.read(); // 接受输入,使程序在此停顿,一旦接收到用户输入,main线程结束,守护线程自动结束
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

class TestThread extends Thread {
    public void run() {
        for (int i = 1;; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println(i);
        }
    }
}

boolean isDaemon():判断是否是守护线程;
void setPriority(int newPriority):设置线程优先级,默认为5,最小为1,最大为10;优先级越高,越能更早的获取CPU调度;
Thread currentThread():返回当前线程对象的一个引用,为什么不用this?见下篇博客
int activeCount():返回当前线程所在的线程组中活跃线程的数量;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值