java并发编程基础

107 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

并发编程基础

Java 中的线程分为两类,分别为 daemon 线程(守护线程〉和 user 线程(用户线程)。 在 JVM 启动时会调用 main 函数, main 函数所在的线程就是一个用户线程,其实在 JVM 内部同时还启动了好多守护线程,比如垃圾回收线程。 线程会带来额外的开销,如cpu调度

java创建线程的三种方式:

1、继承thread类,重写run()方法,调用start()开启线程

run() 只有主线程一条执行路径;start()多条执行路径,主线程和子线程并行交替执行。

2、实现runnable接口

3、实现callable接口(FutureTask,可以通过get阻塞获取线程结果)

java默认2个线程:main和gc

java无法开启线程,只能调用底层c++,无法操作硬件

并发:cpu一核(充分利用cpu资源) 并行:cpu多核

线程有几个状态

NEW,  //新生
RUNNABLE,
BLOCKED, //阻塞
WAITING,
TIMED_WAITING, //超时等待
TERMINATED; //终止

wait/sleep区别

1、wait()方法属于Object类,sleep()属于Thread类;

2、wait()方法释放cpu给其他线程,自己让出资源进入等待池等待;sleep占用cpu,不让出资源;

3、sleep()必须指定时间,wait()可以指定时间也可以不指定;sleep()时间到,线程处于临时阻塞或运行状态;

4、wait()方法会释放持有的锁,不然其他线程不能进入同步方法或同步块,从而不能调用notify(),notifyAll()方法来唤醒线程,产生死锁,所以释放锁,可以执行其他线程,也可以唤醒自己,只是设置停止自己的时间时不确定的;sleep方法不会释放持有的锁,设置sleep的时间是确定的会按时执行的;

5、wait()方法只能在同步方法或同步代码块中调用,否则会报illegalMonitorStateException异常,如果没有设定时间,使用notify()来唤醒;而sleep()能在任何地方调用,必须捕获异常;

线程礼让 yield()

  • 礼让线程,让当前正在执行的线程暂停,但不阻塞
  • 将线程从运行状态转为就绪状态
  • 让CPU重新调度,礼让不一定成功,看CPU心情

线程强制执行 join()

  • Join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞
  • 可以想象成插队