线程和进程

进程:
        处于运行过程中的程序,具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位
进程三特征:
独立性:有自己的独立资源,拥有地址空间,
动态性:正在系统中活动的指令集合,进程具有自己的生命周期和各种不同的状态
并发性:多个进程可以在单个处理器上并发执行,多个进程之间互不影响
线程
        线程是轻量级的进程,线程是进程的执行单元。线程在程序中是独立的、并发的执行流。当进程被初始化后,主线程就被创建。
        线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、程序计数器和局部变量,但不拥有系统资源,它与父进程的其他线程一起共享父进程的系统资源。

创建线程的三种方式
  1. 继承Thread,实现run()方法;
  2. 类A实现runnable()接口,并完成接口中的run()方法,再创建线程,把类A的实例作为线程的target
  3. callable接口(可抛出异常、有返回值)——类A实现callable接口,并完成里面的call方法,需要常见一个FutrueTask对象来包装类A,再创建线程,把FutureTask作为该线程的Target;FutureTask的get方法可返回call方法的返回值。但get方法会阻塞线程,直到返回值返回后,线程方能继续执行。
线程的生命周期: 新建、就绪、运行、阻塞、死亡

join线程
Thread提供了让一个线程等待另一个线程的方法
线程A   调用了线程B的join方法,那么线程A将被阻塞,等待线程B执行完毕后,再回复线程A继续执行。

线程同步
synchronized (包含隐式同步监视器)—
  1. 可用wait控制当前线程,导致当前线程等待
  2. notify唤醒此同步监视器上等待的单个线程
  3. notifyAll唤醒此同步监视器上等待的所有线程
lock 锁  需要显示释放锁,因此经常与try catch块一起用,将释放工作放在finally块中完成

使用阻塞队列控制线程通信
BlockingQueue  put/take

线程池
        系统启动和销毁新线程的成本比较高,它涉及与操作系统的交互,当程序中需要创建大量生存期短暂的线程时,考虑使用线程池。线程池启动时会创建大量的空闲线程,程序将callable或runnable对象传递给线程池,线程池就会启动一个线程在执行对应的run0方法或者call()方法,当执行结束后,线程并不会死亡,而是重新返回线程池中变为空闲线程,等待下一个任务。

线程池的实现
Executor 工厂类来产生线程池,该工厂类包含如下几个静态工厂方法来创建线程池:
  1. newCatchedThreadPool() ——具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中
  2. newFixedThreadPool(int nThread)——可重用,具有固定线程数的线程池
  3. newSingleThreadExecutor()——创建只有一个单线程的线程池,
  4. newScheduledThreadPool(int corePoolSize)——具有指定线程数的线程池,可以指定延迟后执行线程任务
  5. newSingleThreadScheduledExecutor()——只有一个线程的线程池,可以在指定延迟后执行

    前三种方法返回一个 ExecutorServer 对象,代表一个线程池,可以执行runnable和callable任务;后两个方法返回 ScheduledExecutorServer 线程池,可以指定延迟后执行任务

线程池使用步骤
  1. 调用Executors类的静态工厂方法,创建一个 ExecutorService对象,该对象代表一个线程池;
  2. 创建Runnable实现类或Callable实现类的实例,作为线程执行任务;
  3. 调用ExecutorService对象的submit()(有返回值)或execute()(无返回值)方法,来提交Callable或Runnable实例;
  4. 当不想提交任何任务时,调用ExecutorService对象的shutdown()方法来关闭线程池

ForkJoinPool   并行执行的线程池实现类
        ForkJoinPool是ExecutorService的实现类,是一种特殊的线程池;支持将一个任务拆分成多个“小任务”计算,再把小任务的结果合并成总的计算结果。
        使用方式:
  1. 创建ForkJoinPool实例
  2. 调用submit(ForkJoinPoolTask   task)或者invoke(ForkJoinTask  task)方法来执行指定任务
ForkJoinTask代表一个可并行、合并的任务,是个抽象类,有两个抽象子类: RecursiveAct ion(表示没有返回值的任务)   和   RecursiveTask (有返回值的任务)

线程相关类
ThreadLocal类 :给每个线程一个线程局部变量的副本,隔离多线程程序的资源竞争。
同步机制:多线程之间共享资源,达到线程之间互相通信,则用同步机制
包装线程不安全类: Collections.synchronizedXxx  将集合包装成线程安全类
example:HashMap  hm=Collections.synchronizedMap(new HashMap());——创建后立即包装

线程状态变换
新建(new,但未start)
就绪(start)——除处理机,其他资源均到位(由新建转换得到,还可由阻塞状态变换得到,如下所示)
运行:获得处理器,正在执行过程
阻塞:由运行状态转换得到:遇到如下情形会有运行-->到阻塞
  1. sleep()
  2. IO阻塞
  3. 等待同步锁
  4. 等待通知(notify  notifyAll)
  5. suspend(不常用)
就绪:除了start,可由阻塞状态转换得到,转换条件如下:
  1. sleep()时间到
  2. IO方法返回
  3. 获得同步锁
  4. 收到通知
  5. resume
死亡:死亡不可逆,由运行状态转换得到:转换条件如下:
  1. stop
  2. Error或Exception
  3. run/call执行完毕

Java中的线程进程是操作系统中两个基本的概念,它们在执行上下文中有着不同的含义: 1. **进程**(Process): 进程是操作系统分配资源的基本单位,每个进程都有自己的独立内存空间和系统资源。Java程序运行时会创建一个对应的JVM(Java Virtual Machine),JVM中可以有多个并发执行的线程进程的切换是由操作系统内核控制的,切换开销相对较高。 2. **线程**(Thread): 线程是在同一个进程中并行执行的轻量级实体,它们共享同一块内存空间,因此相比于进程线程之间的通信更快、切换更频繁。在Java中,每个Java应用至少有一个主线程,用户可以通过继承Thread类或实现Runnable接口来创建新的线程。 **主要区别**: - **资源占用**:进程拥有独立的内存空间,而线程共享进程的内存,所以线程更节省资源。 - **并发性**:同一进程内的线程可以直接相互访问数据,易于实现并发控制;而不同进程间的数据交换需要通过I/O操作。 - **调度粒度**:进程调度由操作系统进行,线程调度则由JVM或操作系统的用户级线程管理器完成,线程切换更快速。 - **同步与通信**:线程之间通常通过锁、条件变量等同步机制协作,而进程间的通信通常使用管道、消息队列等机制。 **相关问题**: 1. Java如何创建和管理线程? 2. 进程线程在性能优化上有什么考虑? 3. 在并发编程中,为什么要避免不必要的线程创建?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值