synchronized

多线程笔记

梦想的初衷 提交于 2020-01-10 03:57:59
1.sleep方法不会释放持有的锁 2.synchronized锁机制。同步代码块,对同意对象申请锁 Thread thread1=new Thread(new Runnable() { @Override public void run() { synchronized (list){ for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } } }); Thread thread2=new Thread(new Runnable() { @Override public void run() { synchronized (list){ list.clear(); } } }); thread1.start(); thread2.start(); synchronized方法,作用跟synchronized代码块一样,多个线程在调用不同的synchronized方法时 public synchronized void bianli(){} 静态synchronized方法获得的是当前类的.class对象的锁 对象的wait(),notify()方法,wait会释放锁,其它现成执行,notify会通知等待的线程继续执行。通知所有等待的线程使用notifyAll.当notify的线程执行完

java-线程

梦想的初衷 提交于 2020-01-10 03:28:34
一、状态 java线程存在以下几种状态: 1: 创建状态(New):线程被new出来,还未调用start 2: 就绪状态(Runnable):又称为可执行状态,调用线程的start方法后,线程处于就绪状态,,线程调度程序还未给该线程分配cpu时间片执行。 3: 运行状态(Running):线程调度程序分配cpu时间片来执行线程代码。 4: 阻塞状态(Blocked):线程在运行过程中由于某种原因暂停运行进入阻塞状态,只有满足条件后进入就绪状态,获取cpu后才能再次进入运行状态。 阻塞的情况分三种: A:等待阻塞(wait):调用wait()方法,与synchroined一起使用,线程进入对象等待池,释放synchroined的锁,处于阻塞状态。当有其他线程notify,notifyAll后线 进入锁标识等待池,即进入同步阻塞状态。 B:同步阻塞:线程运行过程中需要获取锁,但该锁被其他线程持有,则该线程进入锁标识等待池,处于同步阻塞状态。当线程获取锁之后,线程进入就绪状态。 C:其他阻塞:当线程sleep,或者join,或者发出I/O请求后,知道yield时间到,sleep时间到,join的线程执行完,或者I/O返回后,线程进入就绪状态。 5: 死亡状态(Dead):当线程Run方法退出或者运行出现异常线程停止时,线程就会消亡。 二、synchronized的用法

Java多线程8:wait()和notify()/notifyAll()

匆匆过客 提交于 2020-01-09 20:27:20
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作。 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处理?一个办法就是,B线程while(i == 10000),这样两个线程之间就有了通信,B线程不断通过轮训来检测i == 10000这个条件。 这样可以实现我们的需求,但是也带来了问题:CPU把资源浪费了B线程的轮询操作上,因为while操作并不释放CPU资源,导致了CPU会一直在这个线程中做判断操作。如果可以把这些轮询的时间释放出来,给别的线程用,就好了。 wait/notify 在Object对象中有三个方法wait()、notify()、notifyAll(),既然是Object中的方法,那每个对象自然都是有的。如果不接触多线程的话,这两个方法是不太常见的。下面看一下前两个方法: 1、wait() wait()的作用是使当前执行代码的线程进行等待,将当前线程置入"预执行队列"中,并且wait()所在的代码处停止执行,直到接到通知或被中断。 在调用wait()之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()方法 。 2、notify() notify()的作用是,如果有多个线程等待,那么线程规划器随机挑选出一个 wait的线程,对其发出通知notify

Java哲学家进餐问题|多线程

白昼怎懂夜的黑 提交于 2020-01-09 16:53:48
Java实验三 多线程 哲学家进餐问题: 5个哲学家共用一张圆桌,分别坐在周围的5张椅子上, 在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双), 碗和筷子交替排列。他们的生活方式是交替地进行思考(thinking)和进餐(eating)。 平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的两只筷子,规定他必须先取左边的筷子,再取右边的筷子。 只有在他拿到两只筷子时才能进餐。 进餐完毕,放下筷子继续进行思考。 假如5位哲学家同时饥饿,各自拿起左边的筷子时,再去拿各自右边的筷子,因为无筷子可拿而陷入无期限等待(死锁)。 一种解决的办法是:至多只允许有4位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够拿到两只筷子,从而进餐。 进餐完毕释放他用过的两只筷子,从而使更多的哲学家能够进餐。使用Java的多线程同步技术,实现上述解决方案。 思路都在代码里了 代码出错了 代码已改正,主要就是synchronized定义同步代码块,Num的值设置条件使不发生死锁 代码被检查了,Num也是全局变量,有可能在多线程调度时,当前线程执行num++前,另一个线程也进入了if(num<4)的代码块,理论上可能出了某些问题,仅供参考 但我感觉是没有问题的,synchronized会使多线程代码串行执行嘛,进入synchronized(left)后才给num+1,既然是串行

Synchronized、Threadlocal、Volatile

感情迁移 提交于 2020-01-09 14:38:28
synchronized: synchronized叫做同步锁,操作起来方便,只需要在一个方法或把需要同步的代码块包装在它内部,那么这段代码就是同步的了,所有线程对这块区域的代码访问必须先持有锁才能进入,否则则拦截在外面等待正在持有锁的线程处理完毕再获取锁进入正因为它基于这种阻塞的策略,所以它的性能不太好,但是由于操作上的优势, 只需要简单的声明一下即可,而且被它声明的代码块也是具有操作的原子性。 threadlocal (本地单机) 用来提供线程内的局部变量,这样每个线程都自己管理自己的局部变量,别的线程操作的数据不会对我产生影响,互不影响 就是把变量分成很多个拷贝,每个线程拥有一个。这里没有所谓的最后的结果,每个线程单独操作自己的变量,和其他的变量没关系,互不干扰 ThreadLocalMap类的定义是在ThreadLocal类中,真正的引用却是在Thread类中。同时,ThreadLocalMap中用于存储数据的entry定义,它是一个Map,他的key是ThreadLocal实例对象。 1、JVM利用设置ThreadLocalMap的Key为弱引用,来避免内存泄露。 2、JVM利用调用remove、get、set方法的时候,回收弱引用 3、当ThreadLocal存储很多Key为null的Entry的时候,而不再去调用remove、get、set方法,那么将导致内存泄漏 4

java synchronized method - how does it work

女生的网名这么多〃 提交于 2020-01-09 10:24:09
问题 I think I know this, but would like it confirming. Obviously the synchronized blocks other threads from accessing it, but I see and awful lot of examples such as public synchronized void setValue(int value) { balance=value; } Am I right in thinking, that if the method only does one line like the above, then there is no point in it being synchronized. Thanks 回答1: Am I right in thinking, that if the method only does one line like the above, then there is no point in it being synchronized. No.

[转帖]synchronized、lock和cas理解

徘徊边缘 提交于 2020-01-08 23:59:14
synchronized、lock和cas理解 https://blog.csdn.net/qq_41908272/article/details/94736856 这是小编我在看完ReentrantLock类之后对这几种可以实现锁的方式的理解,如果有什么理解的不对的,大家可以一起交流,共同进步。 synchronized synchronized这个关键子是java语言中可以用于实现锁的一种方式。这个关键字我们一般称为同步。这种加锁的方式也是我们平常经常用到的,就比如说小编前段时间碰到的一个问题,用户领取优惠券,这时发现一个用户在领取优惠券时都会发生多领的情况,不用考虑,直接加锁,这是可以不费吹灰之力就可以解决问题的方式。但是加在哪里,怎么加这是很有可能会影响到系统的运行速度。现在先来看下synchronized可以加在哪几个地方,并说一下加在这些地方会对什么东西上锁。 //1⃣️ synchronized (this){ } //2⃣️ public synchronized void tset(){ } //3⃣️ synchronized (类名.class){ } 在上面的代码块中,这是synchronized可以加在这几个地方,加在不同的地方锁住的对象也是不同的,就比如说1和3,就是锁住当前进入这个方法的实例,即是锁住对象,2就是锁住这个方法

Java 并发进阶常见面试题总结

孤街浪徒 提交于 2020-01-08 23:06:27
Java 并发进阶常见面试题总结 1. synchronized 关键字 1.1. 说一说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。 另外,在 Java 早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,这也是为什么早期的 synchronized 效率低的原因。庆幸的是在 Java 6 之后 Java 官方对从 JVM 层面对synchronized 较大优化,所以现在的 synchronized 锁效率也优化得很不错了。JDK1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。 1.2. 说说自己是怎么使用 synchronized 关键字,在项目中用到了吗 synchronized关键字最主要的三种使用方式: 修饰实例方法:

线程编程方面

一笑奈何 提交于 2020-01-08 21:25:05
1. Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 三种实现方法 1.继承 Thread 类 扩展性差 无返回值 2, 实现 Runnable 接口 可扩展 无返回值 3. 实现 Callable 接口 有返回值 用synchronized关键字修饰同步方法 反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。 2. sleep() 和 wait() 有什么区别? 答: sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复

正确使用 Volatile 变量

送分小仙女□ 提交于 2020-01-08 03:48:37
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。 与锁相比,Volatile 变量是一种非常简单但同时又非常脆弱的同步机制,它在某些情况下将提供优于锁的性能和伸缩性。如果严格遵循 volatile 的使用条件 —— 即变量真正独立于其他变量和自己以前的值 —— 在某些情况下可以使用volatile 代替 synchronized 来简化代码。然而,使用 volatile 的代码往往比使用锁的代码更加容易出错。 为了提高处理速度