多线程实现

多线程实现对比

Java多线程启动

·启动

  • start方法,会自动以新进程调用run方法(并行运行(多线程运行))
  • 直接调用run方法,将变成串行执行
  • 同一个线程,多次start会报错,只执行第一次start方法
  • 多个线程启动,其启动的先后顺序是随机的
  • 线程无需关闭,只要其run方法执行结束后,自动关闭
  • main函数(线程)可能早于新线程结束,整个程序并不终止
  • 整个程序终止是等所有的线程都终止(包括main函数线程)

Thread vs Runnable

-Thread占据了父类的名额,不如Runnable方便

-Thread类实现Runnable

-Runnable启动时需要Thread类的支持

-Runnable更容易实现多线程中资源共享

结论:建议实现Runnable接口来完成多线程

多线程信息共享

-static变量(不同线程之间操作变量时不可见)

-同一个Runnable类的成员变量

-采用volatile关键字修饰变量(保证不同线程对共享变量操作时的可见性)

关键步骤加锁限制

一互斥:某一个线程运行一个代码段(关键区),其他线程不能同时运行这个代码段

一同步:多个线程的运行,必须按照某一种规定的先后顺序来运行

一互斥是同步的一种特例
互斥的关键字是synchronized

-synchronized代码块/函数,只能一个线程进入

-synchronized加大性能负担,但是使用简便

线程状态

-创建(new)

-就绪(start)

-运行(run)

-阻塞(sleep)

-结束

线程阻塞/和唤醒

  • sleep,时间一到,自己会醒来
  • wait/ notify/notifyAll,等待,需要别人来唤醒
  • join,等待另外一个线程结束
  • interrupt,向另外一个线程发送中断信号,该线程收到信号,会触发InterruptedException(可解除阻塞),并进行下一步处理

生产者和消费者问题

多线程死锁

-每个线程互相持有别人需要的锁(哲学家吃面问题)

-预防死锁,对资源进行等级排序
守护(后台)线程(setDaemon(true))
-普通线程的结束,是run方法运行结束

-守护线程的结束,是run方法运行结束,或main函数结束

-守护线程永远不要访问资源,如文件或数据库等

·线程查看工具jvisualvm

并行计算

线程组管理ThreadGroup

—线程的集合

—树形结构,大线程组可以包括小线程组

—可以通过enumerate方法遍历组内的线程,执行操作

—能够有效管理多个线程,但是管理效率低

—任务分配和执行过程高度耦合

一重复创建线程、关闭线程操作,无法重用线程

Executor框架

Executor FrameWork (java.util.concurrent.*)

一分离任务的创建和执行者的创建

一线程重复利用(new线程代价很大)·理解共享线程池的概念

一预设好的多个Thread,可弹性增加一多次执行很多很小的任务

一任务创建和执行过程解耦

一程序员无需关心线程池执行任务过程

主要类:ExecutorService, ThreadPoolExecutor,Future

—Executors.newCachedThreadPool/ newFixedThreadPool创建线程池

—ExecutorService线程池服务

—Callable具体的逻辑对象(线程类)

— Future返回结果

原文地址:https://www.cnblogs.com/junfblog/p/14504919.html