java线程基础

一、定义一个线程(Defining a Thread)有两种方法

继承Thread接口

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("我在运行");
    }
}

实现java.lang.Runnable接口

public class MyThread implements Runnable {
    @Override
    public void run() {
            System.out.println("我在运行");
    }
}

2、启动线程

MyThread mythread = new MyThread();
mythread.start();

3、线程的5种状态

    新生状态(New): 当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生(new)状态,处于新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(not alive);

  就绪状态(Runnable): 通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable);处于就绪状态的线程已经具备了运行条件,但还没有被分配到CPU即不一定会被立即执行,此时处于线程就绪队列,等待系统为其分配CPCU,等待状态并不是执行状态; 此时线程是活着的(alive);

  运行状态(Running): 一旦获取CPU(被JVM选中),线程就进入运行(running)状态,线程的run()方法才开始被执行;在运行状态的线程执行自己的run()方法中的操作,直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡;如果在给定的时间片内没有执行结束,就会被系统给换下来回到线程的等待状态;此时线程是活着的(alive);

  阻塞状态(Blocked):通过调用join()sleep()wait()或者资源被暂用使线程处于阻塞(blocked)状态;处于Blocking状态的线程仍然是活着的(alive)

  死亡状态(Dead):当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象,当该Thready已经不可能在被作为一个可被独立执行的线程对待了,线程的独立的call stack已经被dissolved。一旦某一线程进入Dead状态,他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法,会出现一个运行期(runtime exception)的异常;处于Dead状态的线程不是活着的(not alive)。

4、线程池
首先整理下线程池的相关接口

Executor:顶级接口,只定义了一个void execute(Runnable command)方法
ExecutorService:该接口继承了Executor接口并声明了
    shutdown: 关闭线程池,正在运行和等待运行的任务无法interrupt,仍会运行只有尚未运行的会被打断。
    shutdownNow: 关闭线程池,尝试关闭所有任务,并返回尚未执行的task的list
    isShutdown: 判断线程池是否被关闭(关闭:true)
    submit: 内部调用的也是execute(),用来向线程池提交任务的,通过Future可以返回任务执行的结果
    invokeAll(Collection<? extends Callable<T>> tasks): 批量提交任务
    invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit): 批量提交任务,超出timeout时间范围未执行的任务会被取消

    submit和execute的区别:
        1、submit可以返回任务运行的结果,execute不可以
        2、submit如果不调用返回的Future对象的get方法不会抛出线程中的异常
invokeAll用法

public class Main {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        List<MyCallable> callables = new ArrayList<>();
        for(int i = 1; i <= 5; i++) {
            callables.add(new MyCallable(10,i));
        }
        try {
            List<Future<Integer>> futures = threadPool.invokeAll(callables, 10, TimeUnit.SECONDS);
            System.out.println("运行结束");
            for (int i = 0; i < futures.size(); i++) {
                System.out.println(futures.get(i).get());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }  finally {
            threadPool.shutdownNow();
        }
    }
}
class MyCallable implements Callable<Integer>{
    private int price;
    private int num;
    public MyCallable(int price, int num){
        super();
        this.price = price;
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        Thread.sleep(3000);
        System.out.println("用时3s,结果为:"+price*num);
        return price*num;
    }
}
运行结果:
用时3s,结果为:10
用时3s,结果为:20
用时3s,结果为:30
运行结束
shutdown和shutdownNow实例
shutdown()方法:
    public static void main(String[] args){
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            int a = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(a);
                }
            });
        }
        threadPool.shutdown();
    }
结果:打印0-9
shutdownNow()方法:
public static void main(String[] args){
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            int a = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(a);
                }
            });
        }
        List<Runnable> runnables = threadPool.shutdownNow();
        System.out.println(runnables);
    }
结果:打印0以及9个未执行的任务:
[Main$1@6e0be858, Main$1@61bbe9ba, Main$1@610455d6, Main$1@511d50c0, Main$1@60e53b93, Main$1@5e2de80c, Main$1@1d44bcfa, Main$1@266474c2, Main$1@6f94fa3e]

创建线程池的集中方法:

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务
ExecutorService singlePool = Executors.newSingleThreadExecutor();
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(5);
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
ExecutorService cachedPool = Executors.newCachedThreadPool();
singlePool fixedPool cachedPool 用下面形式创建
singlePool.execute(new Runnable() {
            @Override
            public void run() {
                throw new NullPointerException();
//                System.out.println(1);
            }
        });
推迟3秒调度
scheduledPool.schedule(new Runnable() {
            public void run() {
                System.out.println("delay 3 seconds");
            }
        }, 3, TimeUnit.SECONDS);
首次运行推迟3秒,之后每1秒运行一次
scheduleAtFixedRate()固定时间调度一次
scheduleWithFixedDelay()运行时间+固定时间调度一次
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值