Java多线程

本文详细介绍了Java多线程的声明周期、实现方式(Runnable、Callable、Thread)、线程管理(sleep、yield、守护线程)、线程同步、线程调度(线程优先级、睡眠、等待、让步、加入、唤醒)以及常用函数,如sleep、join、wait和notify。此外,还讨论了经典的生产者-消费者问题。
摘要由CSDN通过智能技术生成

Java多线程

一.多线程的声明周期
状态名称 说明
New 初始状态,线程被构建,但是还没有调用start()方法
RUNNABLE 运行状态,Java线程将操作系统中处于就绪和运行两种状态“笼统”地称作“运行中”
BLOCKED 阻塞状态,表示线程阻塞于锁
WAITING 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定的动作(通知或中断)
TIME_WAITING 超时等待状态,该状态不同于WAITING,它是可以在指定的时间自行返回的
TERMINATED 终止状态,表示当前线程已经执行完毕
二.使用线程

有三种使用线程的方法:

  • 实现Runnable接口;
  • 实现Callable接口;
  • 继承Thread方法;
实现Runnable接口

需要实现run方法。通过Thread调用start()方法来启动线程。

public class MyRunnable implements Runnable{
   
    public void run(){
   
        //...
    }
}
public static main(String[] args){
   
    MyRunnable instance = new MyRunnable();
    Thread thread = new Thread(instance);
    thread.start();
}
实现Callable接口

需要实现call()方法,与Runnable相比,Callable可以有返回值,通过call()方法返回,返回值通过FutureTask进行封装。

public class MyCallable implements Callable<Integer> {
   
    public Integer call() {
   
        return 123;
    }
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
   
    MyCallable myCallable = new MyCallable();
    FutureTask ft = new FutureTask(myCallable);
   	Thread thread = new Thread(ft);
    thread.start();
    System.out.println(ft.get());
}
继承Thread类

同样也需要实现run()方法,因为Thread类也实现了Runnable接口。

当调用start()方法启动一个线程时,虚拟机会将该线程放入就绪队列中等待调度,当一个线程被调度时会执行该线程的run()方法。

public class MyThread extends Thread{
   
    public void run(){
   
        //...
    }
}
public static void main(String[] args){
   
    MyThread myThread = new MyThread();
    myThread.start();
}

实现接口和VS继承Thread类,实现接口会更好一点,因为:

  • Java不支持多继承,因此继承了Thread类就无法继承其他类,但是可以实现多个接口。
  • 类可能只要求可执行就行,继承整个Thread类开销过大。

总结:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类

提醒一下大家:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。

三.线程管理
  1. 如果我们需要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用Thread的sleep方法。sleep()是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。
public class Test1 {
     
    public static void main(String[] args) throws InterruptedException {
     
        System.out.println(Thread.currentThread().getName());  
        MyThread myThread=new MyThread();  
        myThread.start();  
        myThread.sleep(1000);//这里sleep的就是main线程,而非myThread线程  
        Thread.sleep(10);  
        for(int i=0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值