Java多线程概念(一)

圣手书生
• 阅读 831

线程安全:

通过加锁保证数据的一致性.也就是说当一个线程访问某个数据时,通过加锁操作对数据进行保护,其它线程在加锁期间不能对其访问

线程封闭

当多个线程访问共享变量时,需要通过加锁来保证数据同步,增加了程序的复杂性. 避免数据同步的一种方式是不共享变量,比如使用局部变量和ThreadLocal

线程调度

系统为线程分配CUP使用权的过程
  • 协同式线程调度
线程的执行时间由线程自己控制,当自己执行完后,主动通知操作系统切换到另外一个线程上执行. 好处是实现简单,线程对自己的操作是可知道的,没有什么线程同步问题.缺点是线程执行时间不可控,如果一个线程有问题,可能会一致阻塞在那里.
  • 抢占式线程调度
每个线程的执行时间有操作系统分配,线程的切换不由线程本身决定(Java中,Thread.yield()可以让出执行时间,但无法获取执行时间)线程执行时间系统可控,也不会有一个线程导致进程阻塞.

java线程调度就是抢占式调度

可以通过设置线程的优先级让一些线程尽可能的先执行多执行(Java一共有10个线程优先级从Thread.MIN_PRIORITY至Thread.MAX_PRIORITY),在两个线程同时处于ready时,优先级越高越容易被执行.但优先级并不靠谱,因为Java线程时通过映射到原生线程来实现的,所以线程调度还是取决于操作系统.

状态转换

  • 新建(New)创建后尚未启动的线程
  • 运行(Runnable):Runnable包括操作系统中的Running和Ready. 处于此状态的线程有可能在运行,也有可能在等待CPU为它分配执行时间.线程创建后,其它线程调用了该线程的start方法,那么该线程就位于可运行线程池中,变得可运行,就差CPU分配执行时间,其它运行所需要的资源都已经获得.
  • 无限期等待(Waiting):该状态下的线程不会被分配CPU执行时间,要等待被其它线程进行显示唤醒. 如没有设置timeout的Object.wait()方法和Thread.join()方法,以及LockSupport.park()方法
  • 限时等待(Timed Waiting):该状态下的线程不会被分配CPU执行时间,只不过不需要被显示的唤醒,在一定时间后会被系统自动唤醒. 如Thread.sleep(),设置了timeout的Object.wait()和Thread.join(),LockSupport.parkNanos()以及LockSupport.parkUntil()方法
  • 阻塞(Blocked):线程被阻塞了,与等待的区别是:阻塞线程在等待一个排它锁.
阻塞状态是因为某种原因放弃CPU使用权,暂时停止执行,直到线程进入就绪状态,才有机会转到运行状态.
  • 结束(Terminated):线程执行完了或者异常退出了run()方法,该线程结束生命周期

阻塞常见的三种情况

1.等待阻塞(无限期等待):运行的线程执行wait()方法,该线程会释放占用的资源,JVM会把该线程放入等待池.进入这个状态后,线程不会自动唤醒,必须依靠其它线程调用notify()或notifyAll()方法才能会被唤醒.

2.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被其它线程占用,则JVM会把该线程放入锁池.
3.其它阻塞(限时等待):运行的线程执行了join()或者sleep()方法,或者发起了I/O请求,JVM会把该线程置为阻塞状态,当sleep()状态超时,join()等待线程终止或者超时,I/O处理完成,该线程重新转入就绪状态.

Java多线程概念(一)

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java的静态方法加锁与一般方法加锁
第一部分: synchronized 与staticsynchronized  的区别第二部分:java多线程锁,源码剖析1、synchronized与staticsynchronized的区别   synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块。  stat
Wesley13 Wesley13
3年前
java多线程加锁的简单处理办法
    当对数据修改时,如果两个线程同时去修改同一条数据,这样产生的结果就不是我们预期的结果。这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。    下面是一个未加锁的修改方法:   public void update(Entry entry){    dao.update(entry);
Wesley13 Wesley13
3年前
java 面试知识点笔记(十)多线程与并发
问:线程安全问题的主要诱因?1.存在共享数据(也称临界资源)2.存在多条线程共同操作这些共享数据解决方法:同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再对共享数据进行操作互斥锁的特征:1.互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程协调机制,这样在同一时间只有一
Stella981 Stella981
3年前
ConcurrentHashMap介绍
在进行结构性修改,如put/remove/replace时都需要进行加锁,但是读取并未加锁,并发情况下,由于内存不同步问题,会导致一个线程的写操作并不会立即对另一个线程可见。这里ConcurrentHashMap通过volatile变量的内存可见性特性来保证一个线程的写操作立即被其他线程可见,每个方法在一开始都会读取count这个变量,该变量就是一个vola
Wesley13 Wesley13
3年前
Java并发编程原理与实战十八:读写锁
ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程。基本规则:读读不互斥读写互斥写写互斥问题:既然读读不互斥,为何还要加读锁答:如果只是读,是不需要加锁的,加锁本身就有性能上的损耗如果读可以不是最新数据
Wesley13 Wesley13
3年前
4种常用Java线程锁的特点,性能比较及使用场景
多个线程同时对同一个对象进行读写操作,很容易会出现一些难以预料的问题。所以很多时候我们需要给代码块加锁,同一时刻只允许一个线程对某个对象进行操作。多线程之所以会容易引发一些难以发现的bug,很多时候是写代码的程序员对线程锁不熟悉或者干脆就没有在必要的地方给线程加锁导致的。本篇我想分享java多线程中的4种常见线程锁的特点、性能比较及使用场景。一、多线
Wesley13 Wesley13
3年前
Java并发编程之锁的活跃性问题
引子在安全性和活跃性之间通常存在一种制衡。当我们使用锁来保证线程的安全的同时,如果过度使用加锁,可能会导致死锁。应用无法从死锁中恢复过来,所以在设计时一定要避免会排除这些可能会出现的活跃性问题。死锁死锁描述了这样一种情景,两个或多个线程永久阻塞,互相等待对方释放资源如果线程1锁住了A,然后尝试对B进行加锁,同
Wesley13 Wesley13
3年前
Java多线程——线程封闭
线程封闭:当访问共享的可变数据时,通常需要同步。一种避免同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步,这种技术称为线程封闭(thread confinement)  线程封闭技术一个常见的应用就是JDBC的Connection对象,JDBC规范并没有要求Connection对象必须是线程安全的,在服务器应用程序中,线程从连接
ReentrantLock源码解析 | 京东云技术团队
并发指同一时间内进行了多个线程。并发问题是多个线程对同一资源进行操作时产生的问题。通过加锁可以解决并发问题,ReentrantLock是锁的一种。
深入理解分布式锁:原理、应用与挑战| 京东物流技术团队
前言在单机环境中,我们主要通过线程间的加锁机制来确保同一时间只有一个线程能够访问某个共享资源或执行某个关键代码块,从而防止各种并发修改异常。例如,在Java中提供了synchronized/Lock。但是在分布式环境中,这种线程间的锁机制已经不起作用了,因
京东云开发者 京东云开发者
5个月前
深入理解分布式锁:原理、应用与挑战
作者:京东物流刘浩前言在单机环境中,我们主要通过线程间的加锁机制来确保同一时间只有一个线程能够访问某个共享资源或执行某个关键代码块,从而防止各种并发修改异常。例如,在Java中提供了synchronized/Lock。但是在分布式环境中,这种线程间的锁机制