多线程1

一、java中实现多线程的方式

1、实现Runnable接口

2、继承Thread类

3、实现Callable接口通过FutureTask包装器来创建Thread线程

二、线程的六种状态

NEW 初始状态 线程被构建,但没有执行start()方法
RUNABLE 运行状态 java线程将操作系统中的就绪和运行中状态统称为运行状态
BLOCKED 阻塞状态 线程阻塞于锁
WAITING 等待状态 表示线程进入等待状态,进入该状态的现场需要等待其他线程做一些特定动作
TIME_WAITING 超时等待状态 线程进入等待状态,可以在指定时间后自动返回
TERMINATED 终止状态 当前线程已经执行完毕

 

 

 

 

 

 

 

 

 

 

三、主要的方法

1、sleep()

Thread类的静态方法,使当前正在执行的线程让出CPU资源,当前线程进入阻塞状态,休眠时间到转为就绪状态。

2、yield()

Thread类的静态方法,使当前正在运行的线程让出CPU资源,与sleep()不同的事,该线程立即进入就绪状态,不会进入阻塞状态。

3、join()

     对象方法,使当前线程等待加入线程执行完毕或超时后进入就绪状态。

4、结束线程

Thread.stop()、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit这些终止线程运行的方法已经被废弃了,使用它们是极端不安全的!想要安全有效的结束一个线程,可以使用下面的方法:

    • 正常执行完run方法,然后结束掉;

    • 控制循环条件和判断条件的标识符来结束掉线程。

四、线程同步

1、synchronized

① 同步方法

② 同步代码块

2、volatile

  • 保证了变量的可见性,不能保证原子性
  • volatile告诉JVM该变量在寄存器中的值是不确定的,需要从主存中读取。
  • synchronized是锁定当前变量,只有获得了锁的当前变量才能访问。
  • volatile仅仅能使用在变量级别,synchronized可用在变量、方法、类级别;
  • volatile不会造成线程阻塞,synchronized会导致线程阻塞

3、使用重入锁(Lock)实现线程同步

ReentrantLock

① 等待可中断

② 公平锁

③ 锁绑定多个条件

五、线程通信

  • 为什么wait()、notify()、notifyAll()方法必须在同步方法中进行?

① wait()方法的作用是释放当前线程持有的锁,只有拥有锁才有资格释放;

② notify()方法通常是告知其他线程,某种状态已经被设置完成。

六、线程池

① 降低资源消耗:通过重复利用已创建的线程来降低线程创建和销毁造成的消耗。

② 提高响应速度:到达的任务可立即执行,无需等待线程创建的过程。

③ 提高线程的可管理性:可以会线程进行合理分配、调优和监控

1、实现方式

① Executors工具类

  • newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
返回ExecutorsService类型,具有以下方法
- execute(Runnable):无返回值 - submit(Runnable):返回Future对象,可获取执行结果 - submit(Callable):返回Future对象,可获取返回值 - invokeAny(...):入参为Callable集合,返回任意任务的执行结果 - invokeAll(...):入参为Callable集合,返回所有Future集合,对应每个任务执行后的Future对象。

② ThreadPoolExecutor类

    

 

posted @ 2020-05-17 20:06  啊哈突突突  阅读(118)  评论(0)    收藏  举报