Java进阶6:Java多线程编程

多线程

一个线程的生命周期
  • 线程是一个动态执行的过程,它也有一个从产生到死亡的过程

在这里插入图片描述

  • 新建状态
    使用new、Thread类或者子类建立一个线程对象后,这个线程处于新建状态。它将一直保持在这个状态直到start()

  • 就绪状态
    当线程对象调用了start()方法之后,线程就进入了就绪状态,处于就绪队列中,等待着jvm虚拟机里面线程调度器的调度

  • 运行状态
    如果就绪的线程获取到了CPU的资源,那么就能执行run(),此时线程处于运行状态,处于运行状态的线程最为复杂,可以变为阻塞状态、就绪状态、或者死亡状态

  • 阻塞状态
    如果有一个线程执行了sleep()、suspend()等方法,失去所占用的资源之后,这个线程就会进入阻塞状态。在睡眠时间已到或者获得了设备资源之后就可以重新进入就绪状态

等待阻塞—执行wait()方法,让线程进入到等待阻塞状态
同步阻塞—线程获取到synchronized同步锁失败(被其他线程占用)
其他阻塞—通过调用线程的sleep()或者join()发出了io请求时,线程就会进入到阻塞状态。当sleep()状态超时,join()等待线程终止或者超时,或者io处理完毕,线程重新转入就绪状态。

  • 死亡状态
    一个运行状态的线程完成任务或者其他终止条件发生的时候,这个线程就切换到终止状态
线程的优先级
  • 每一个Java线程都有一个优先级,利于操作系统进行调度
  • Java线程的优先级是一个整数,分别为1-10(最大)
  • 默认情况下每个进程都会分配一个中等优先级5
  • 较高优先级的线程对程序来说更加重要,并且应该优先调度,但是线程不能保证线程执行的顺序,并且非常依赖于平台。
创建线程
  • 三种方法

实现Runnable
继承Thread
通过Callable和Future

实现Runnable接口来创建线程
  • Runnable接口提供了一个run()方法用于调动其他的一些方法
  • 最终还必须通过Thread类来调用自身的线程(类似于Python)
//创建一个实现接口的类
public class multithread implements Runnable {
    private String threadName;
    private Thread thread;
    public multithread(String threadName){
        this.threadName = threadName;
    }
//如果要实现多线程,这个类必须实现run()方法
    public void run(){
        for(int i=0;i<20;i++){
            System.out.println(this.threadName+" is running!");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        System.out.println(this.threadName+" exited!");
    }

    public void start(){
        System.out.println("Starting"+this.threadName);
        if(thread==null){
        //自身新建出一个thread,通过Thread类,通过start()方法来触发
            thread = new Thread(this, threadName);
            thread.start();
        }
    }
}

Startingth1
Startingth2
th2 is running!
th1 is running!
th2 is running!
th1 is running!
th2 is running!
th1 is running!
th2 is running!
th1 is running!
进程已结束,退出代码-1

通过继承Thread类来创建线程
  • 通过本身的类来继承Thread,然后创建一个该类的实例
  • 继承Thread的方式也必须重写run()方法,并且调用start()方法才能执行
public class multithread2 extends Thread{
    private Thread t;
    private String threadName;

    multithread2( String name) {
        threadName = name;
        System.out.println("Creating " +  threadName );
    }

    public void run() {
        System.out.println("Running " +  threadName );
        try {
            for(int i = 4; i > 0; i--) {
                System.out.println("Thread: " + threadName + ", " + i);
                // 让线程睡眠一会
                Thread.sleep(50);
            }
        }catch (InterruptedException e) {
            System.out.println("Thread " +  threadName + " interrupted.");
        }
        System.out.println("Thread " +  threadName + " exiting.");
    }

    public void start () {
        System.out.println("Starting " +  threadName );
        if (t == null) {
            t = new Thread (this, threadName);
            t.start ();
        }
    }
}
通过Callable和Future创建线程
  1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
  2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
  3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
  4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableThreadTest implements Callable<Integer> {
    public static void main(String[] args)
    {
        CallableThreadTest ctt = new CallableThreadTest();
        FutureTask<Integer> ft = new FutureTask<>(ctt);
        for(int i = 0;i < 100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
            if(i==20)
            {
                new Thread(ft,"有返回值的线程").start();
            }
        }
        try
        {
            System.out.println("子线程的返回值:"+ft.get());
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        } catch (ExecutionException e)
        {
            e.printStackTrace();
        }

    }
    @Override
    public Integer call() throws Exception
    {
        int i = 0;
        for(;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
        return i;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值