1 线程相关

1.1 常识

  • 进程:资源分配的基本单位

  • 线程:调度执行的基本单位,多个线程共享一个线程资源

  • 单核CPU设定多线程是否有意义?

  • 线程数是不是设置的越大越好?
    不是,切换线程也需要消耗资源。

  • 工作线程数(线程池中线程数量)设多少合适?

    1. 根据CPU核数来设置线程(不充分,因为现实中并不会仅仅只运行我们的线程);
    2. N t h r e a d s = N C P U ∗ U C P U ∗ ( 1 + W / U ) N_{threads}= N_{CPU} * U_{CPU} * (1 + W/U) Nthreads=NCPUUCPU(1+W/U)
      1. 其中,最佳线程数=CPU核数 × CPU期望利用率 × [1+(I/O耗时(等待时间)/CPU耗时(运行时间))];
      2. 在工程上,线程的数量一般会设置为CPU核数+1,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证CPU的利用率;
    3. 如何得知 W/U ?
      1. JProfiler(一种统计分析工具)
      2. 部署到实际服务器上进行测试

1.2 创建线程的5种方法

  1. 继承Thread类
  2. 实现Runnable接口
  3. Lambda表达式
  4. ThreadPool
  5. Future Callable and FutureTask(可返回值)

note:
本质上只有一种方法:new Tread对象,调用run()方法。

1.3 线程状态

在这里插入图片描述

  1. NEW
  2. RUNNABLE
  3. TIMED WAITING
  4. WAITING
  5. BLOCKED
  6. TERMINATED

1.4 线程的“打断”

面试不怎么考

线程打断的三种方法:
  1. interrupt()
    • 打断某个线程(设置标记位)
  2. isInterrupted()
    • 查询线程是否被打断过(查询标志位)
  3. static interrupted()
    • 查询当前线程(包括主线程)是否被打断过,并重置标志位
    • 如何优雅结束一个线程?
Thead t = new Thread(() -> {
    for(;;) {
        if(Thread.currentThread().isInterrupted()) {
            break;
        }
    }
})
Interrupt和sleep() wait() join():
  • 可以通过Interrupt设置标志位,而后catch InterruptedException来进行处理。
Interrupt和锁:
  • Interrupt不能打断正在竞争锁的线程:synchronized, lock
  • Interrupt可以打断:lockInterruptibly

1.5 线程的“结束”

  • 如何优雅地结束一个线程?
    1. 自然结束(尽量)

    2. stop(): 太粗暴,无论线程处于什么状态,直接关闭,释放所有锁,不会做善后工作,容易造成数据不一致问题。

    3. suspend() resume(): 暂停时不会释放锁,容易造成数据不一致问题。

    4. 使用 volatile 关键字

    5. interrupt() and isInterrupted(比较优雅)

Thead t = new Thread(() -> {
    while(! Thread.currentThread().isInterrupted()) {
        // do something
    }
});

t.start();
//do something
t.interrupt();

Note:
c. d. 都不适合要求精确时间,精确次数的场景,那么什么是合适的?
需要业务线程与外部线程相配合,需要用到锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值