synchronized

等待唤醒(wait / notify)机制

[亡魂溺海] 提交于 2020-01-12 06:55:07
如果一个线程从头到尾执行完也不和别的线程打交道的话,那就不会有各种安全性问题了。但是协作越来越成为社会发展的大势,一个大任务拆成若干个小任务之后,各个小任务之间可能也需要相互协作最终才能执行完整个大任务。所以各个线程在执行过程中可以相互 通信 ,所谓 通信 就是指相互交换一些数据或者发送一些控制指令,比如一个线程给另一个暂停执行的线程发送一个恢复执行的指令,下边详细看都有哪些通信方式。 volatile和synchronized 可变共享变量是天然的通信媒介,也就是说一个线程如果想和另一个线程通信的话,可以修改某个在多线程间共享的变量,另一个线程通过读取这个共享变量来获取通信的内容。 由于原子性操作、内存可见性和指令重排序的存在,java提供了 volatile 和 synchronized 的同步手段来保证通信内容的正确性,假如没有这些同步手段,一个线程的写入不能被另一个线程立即观测到,那这种通信就是不靠谱的~ wait/notify机制 故事背景 也不知道是那个遭天杀的给我们学校厕所的坑里塞了个塑料瓶,导致楼道里如黄河泛滥一般,臭味熏天。更加悲催的是整个楼只有这么一个厕所,比这个更悲催的是这个厕所里只有一个坑!!!!!好吧,让我们用java来描述一下这个厕所: public class Washroom { private volatile boolean

Why do the Java bytecodes for invoking methods implicitly acquire and release monitors?

不羁的心 提交于 2020-01-12 06:50:09
问题 I've been reading up on the Java Virtual Machine Instruction Set and noticed that when using instructions to invoke methods (e.g. invokestatic, invokevirtual, etc.) that are marked synchronized, it's up to that particular bytecode instruction to acquire the monitor on the receiver object. Similarly, when returning from a method, it's up to the instruction that leaves the method to release the monitor when the method is synchronized. This seems strange, given that there are explicit

线程三大特性以及Volatile、ThreadLocal

≯℡__Kan透↙ 提交于 2020-01-12 04:26:14
线程三大特性 多线程有三大特性,原子性、可见性、有序性。 原子性: 即单次或者单组操作要么全部执行(执行的过程不会被任何因素打断)要么就都不执行。 可见性: 即当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 有序性: 程序执行的顺序按照代码的先后顺序执行。 简单来说,原子性保证数据的一致性,是线程安全的一部分,可见性保证多线程之间共享变量的变化能够及时被其它线程发现,有序性是指在一般情况下处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但它保证程序最终执行结果和代码顺序执行的结果是一致的。 重排序对单线程并不会产生任何影响,但在多线程情况下需要考虑。 Volatile Volatile关键字的作用是修饰变量使其在多个线程之间可见,Volatile保证可见性,但是Volatile不具备原子性。 简单来说,使用Volatile关键字可以解决线程之间共享变量可见性问题, 强制线程每次读取该值的时候都去“主内存”中取值。 volatile与synchronized区别? volatile 只能修饰变量,synchronized 可修饰代码块/函数/变量,前者是轻量级的。 volatile 只能保证可见性,不具备原子性,不能用来保证线程同步安全

java多线程安全

心不动则不痛 提交于 2020-01-12 00:27:43
什么是线程安全问题 当多个线程共享同一个 成员变量或者静态变量 . 做 写的操作 肯定会收到其他线程的干扰,导致数据有问题这种现象叫做线程安全问题(做读的操作不会发生数据冲突问题)    示例 :    class threadTrain1 implements Runnable { // 重写run()方法 private static int count = 100; public void run() { while (count > 0) { try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } sale(); } } public void sale() { if (count > 0) { System.out.println(Thread.currentThread().getName() + " 出售 第 " + (100 - count + 1) + " 张票"); count--; } } } public class thread_dame_1 { public static void main(String[] args) { threadTrain1 thread1 = new threadTrain1(); Thread t1 = new Thread(thread1

java锁

妖精的绣舞 提交于 2020-01-11 18:25:17
java中锁的实现有两种:synchronized和ReentrantLock。 synchronized synchronized是java虚拟机的内置锁 对于同步块:编译之后,会在同步块的前后形成 monitorenter 和 monitorexit 两个字节码指令,每个对象都具有一个monitor与之关联,拥有了monitor的线程便锁住了对象。 对于同步方法:编译之后,该同步方法有一个同步标志来表明该方法是同步方法。 synchronized对同一个线程是可重入的,进去一次monitor,count就加1。 java的线程是映射到操作系统的原生系统之上的,如果要阻塞或唤醒一个线程,都需要操作系统来帮忙完成,这就需要从用户态转换到核心态中,状态转换需要耗费很多的时间。所以synchronized属于一个重量级锁。之后虚拟机也进行了优化,比如:自旋锁,自适应自旋锁,轻量级锁,偏向锁。 自旋锁:线程没有获取到锁便进入忙循环,直到获取到锁。 自适应自旋:因为锁占用的时间长的话,自旋的时间太长浪费处理器资源,所以有了自适应自旋,自适应自旋的自旋时间不再固定,而是根据前一次在同一个锁上的自旋时间决定的。如果对于某个锁自旋很少成功,则省掉自旋过程,避免浪费资源,如果刚刚获得过成功,则自旋等待的时间持续相对的更长。 轻量级锁:在不存在锁竞争的时候起作用,当有锁竞争时会膨胀为重量级锁

Synchronized 和 ReentrantLock的区别

孤者浪人 提交于 2020-01-11 16:31:46
Synchronized 和 ReentrantLock的区别: 1、相同点: (1)都是用来协调多线程对共享对象、变量的访问。即防止多个线程同时访问共享资源。 (2)都是可重入锁,同一线程可以多次获得同一个锁 (3)都保证了可见性和互斥性。互斥性就是一个线程得到锁了,其他线程得不到了。 2、区别: (1)ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的。 (2)ReentrantLock 显示的获得、释放锁,synchronized 隐式获得释放锁。 (3)ReentrantLock 可以实现公平锁,ReentrantLock 提供了构造器,能够控制锁是否公平,即FIFO谁先来的,谁先获得锁,获取锁的时候排队。 (4)synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁。 (5)Lock 可以让等待锁的线程响应中断,即在获取锁的过程中可以中断当前线程,而 synchronized 却不行,使用 synchronized 时,等待的线程会一直等待下去,不能够响应中断。 (6)通过 Lock 可以知道有没有成功获取锁,而 synchronized

is synchronized by class name in a function will be valid across extended classes?

爱⌒轻易说出口 提交于 2020-01-11 11:05:02
问题 I have a methode foo in base class uses Synchronized (class name) , and two classes A and B that extends the base class. if i called foo from A instance and B instance in two different thread are they gonna be Synchronized. here's a sample code : class BaseClass { void foo() { synchronized(BaseClass.class) // do something like increment count } } class A extends BaseClass { } class B extends BaseClass { } A a = new A(); B b = new B(); //in thread 1 a.foo() ; //in thread 2 b.foo() ; 回答1: Yes,

is synchronized by class name in a function will be valid across extended classes?

▼魔方 西西 提交于 2020-01-11 11:04:51
问题 I have a methode foo in base class uses Synchronized (class name) , and two classes A and B that extends the base class. if i called foo from A instance and B instance in two different thread are they gonna be Synchronized. here's a sample code : class BaseClass { void foo() { synchronized(BaseClass.class) // do something like increment count } } class A extends BaseClass { } class B extends BaseClass { } A a = new A(); B b = new B(); //in thread 1 a.foo() ; //in thread 2 b.foo() ; 回答1: Yes,

Why can't Thread.interrupt() interrupt a thread trying to acquire lock

断了今生、忘了曾经 提交于 2020-01-11 09:05:33
问题 In the book Thinking in Java it is written that Thread.interrupt() cannot interrupt a thread which is trying to acquire a synchronized lock, I want to know why? 回答1: A blocking operation can be interrupted only if it is declared to throw InterruptedException . Clearly, a synchronized block does not declare it, therefore it is impossible to interrupt a thread while it is waiting to acquire a lock. Alternatively you can use an explicit lock and call Lock.lockInterruptibly() . 回答2: The book is