java多线程

基本概念

  • 多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。在一个程序中,这些独立运行的程序片段叫做“线程”(Thread),利用它编程的概念就叫做“多线程处理”。

原理

  • 实现多线程时采用一种并发机制
  • 并发机制原理:简单地说就是把一个处理器划分为若干个短的时间片,每个时间片依次轮流地执行处理各个应用程序,由于一个时间片很短,相对于一个应用程序来说,就好像是处理器在为自己单独服务一样,从而达到多个应用在同时进行的效果。
  • 多线程就是把操作系统中的这种并发执行机制原理运用在一个程序中,把一个程序划分为若干个子任务,多个子任务并发执行,每一个任务就是一个线程。这就是多线程程序。

优点

  1. 使用线程可以把占据时间长的程序中的任务放到后台去处理。
  2. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
  3. 程序的运行速度可能加快。
  4. 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等。

缺点

  1. 如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。
  2. 更多的线程需要更多的内存空间。
  3. 线程可能会给程序带来更多“bug”,因此要小心使用。
  4. 线程的中止需要考虑其对程序运行的影响。
  5. 通常块模型数据实在多个线程间共享的,需要防止线程死锁的情况发生。

优势

  • 多进程程序结构和多线程程序结构有很大不同,多线程的优势:
    • 方便的通信和数据交换
      线程间有方便的通信和数据交换机制。对于不同进程来说,他们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,这不仅快捷。而且方便。
    • 更高效地利用CPU
      使用多线程可以加快应用程序的响应。这对图形界面的程序尤其有意义,当一个操作耗费时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,因而使用多线程技术,将耗费时长的操作置于一个新的线程,就可以避免这种尴尬的情况
    • 同时,多线程使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同线程运行于不同CPU上。

多线程有什么用

  • 单核:比如一个线程使用的时候CPU计算,IO空闲,IO操作时候CPU空闲,当CPU空闲时,执行另一个线程IO操作对方迟迟没有返回,这时CPU就空闲,而用户阻塞。为了防止阻塞,我们开启多线程。这样提高CPU利用率。
  • 多核:提高CPU利用率,多核分别执行多个线程。比如一个复杂任务,让多核并行,提高效率。

线程、进程、协程区别

  • 进程,是系统分配资源的基本单元,有独立的内存空间,不共享堆,也不共享栈。一个进程至少有一个线程。
  • 线程,是操作系统调度的最小单元,线程拥有自己独立的栈和共享的堆,共享堆,不共享栈。
  • 协程,和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。而线程是CPU进行调度

多线程上下文切换

  • 当CPU只有单核,在执行一个已经运行的线程时候切换到另一个在等待获取CPU执行权的线程,当切换执行权的时候就叫做多线程上下文切换。
  • 上下文切换通常是计算密集型的,上下文切换对系统来说意味着消耗大量的CPU时间,事实上,可能是操作系统中时间消耗最大的操作。
  • linux相比与其他操作系统有很多的优点,其中一项就是,其上下文切换和模式的时间消耗非常少。
    如何减少上下文切换,提高系统操作效率
  • 无锁并发:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁。
  • 使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样就会造成大量线程处于等待状态。
  • 协程:在单线程实现多任务的调度,并在单线程里维持多个任务间的切换。

什么是线程安全

  • 概念
    线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并发执行的程序中,线程安全的代码会通过同步机制保证各线程都可以正常且正确的执行,不会出现数据污染等意外情况。
  • 简介
    一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
    线程安全问题大多是由全局变量静态变量引起的,局部变量逃逸也可能导致线程安全问题。
    若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。
    类要成为线程安全的,首先必须在单线程环境中有正确的行为。如果一个类实现正确,那么没有一种对这个类的对象的操作序列(读或者写公共字段以及调用公共方法)可以让对象处于无效状态,观察到对象处于无效状态、或者违反类的任何不可变量、前置条件或者后置条件的情况。
    此外,一个类要成为线程安全的,要被多个线程访问时,不管运行时环境执行这些线程有什么样的时序安排或者交错,它必须仍然有如上所述的正确行为,并且在调用的代码中没有任何额外的同步。其效果就是,在所有线程看来,对于线程安全对象的操作是以固定的、全局一致的顺序发生的。
    正确性与线程安全性之间的关系非常类似于在描述ACID(原子性、一致性、独立性和持久性)事务时使用的一致性与独立性之间的关系:从特定线程的角度看,由不同线程所执行的对象操作是先后而不是并发执行的。

原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务的操作要么发生,要么都不发生。 一致性(Consistency) 事务前后数据的完整性必须保持一致。 隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability) 事务一旦被提交,他对数据库中的数据的改变就是永久性的,接下来即使数据库发生故障也不会对其有任何影响。

一个线程终止,程序会终止吗

  • 子线程被创建后就跟木县丞没什么关系了。每个线程都要去处理自己的事情,包括异常。当作有线程都结束的时候才说明程序运行结束了。
  • 如果线程的一场没有被捕获的话,这个线程就停止执行了。(如果这个线程持有某个对象监视器,那么这个对象监视器就会被释放)
  • 若有线程调用system.exit()则整个程序终止。

创建线程的方式

  • 继承Thread类
  • 实现Runnable接口
  • 通过Callable和Future创建线程
  • 创建线程池

Runnable和Callable、Future的区别

Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中地代码而已;Callable接口中地call()方法是有返回值地,是一个泛型,和Future、Future Task配合可以用来拿到异步执行地返回值,Callable用于产生结果,Future用于获取结果。
而Callable+Future/Future Task却可以方便获取多线程运行地结果和线程运行状态等信息。

Thread类中地start()和run()方法有什么区别

start()方法被用来启动新创建地线程,而且start()内部调用了run()方法,所以他会开启新线程并执行run方法。
当你调用run方法地时候,只会是在原来地线程中调用方法,没有新的线程启动。所以还是单线程的。

JAVA中++操作符是线程安全的吗

不是,它涉及到多个指令,如变量值的读取,增加,存储回内存,这个过程可能回出现多个线程交叉执行。

什么是线程dump(线程状态)

Java Thread dump记录了线程在jvm中的执行信息,可以看成是线程活动的日志。Java线程转储文件有助于分析应用程序和死锁情况中的瓶颈。使用一些工具比如jstack。可以查看。
新建状态(New)
就绪状态(Runnable)//等待获得CPU的使用权
运行状态(Running)
阻塞状态(Blocked)//阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行
阻塞状态:

  1. 位于对象等待池中的阻塞状态
  2. 位于对象锁池中的阻塞状态
  3. 其他阻塞状态,当前线程执行了sleep()方法

sleep()方法和wait()方法的区别

都造成阻塞

  1. 释放锁:sleep方法没有释放锁,而wait方法释放锁。
  2. 作用:wait通常被用于线程间通信,sleep用于暂停执行。
  3. 苏醒:wait方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyall()方法。sleep()方法执行完成后,线程会自动苏醒。或者可以使用wait(long timeout)超时后线程会自动苏醒。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值