synchronized

J2SE(10)之多线程(线程安全)

[亡魂溺海] 提交于 2020-02-01 05:07:34
1、线程安全 在多线程系统中,当多个线程共享同一份资源时,会出现线程不安全的情况。我们可以使用关键字synchronized加锁来解决线程不安全的问题。 1.1 同步方法 在方法上加上synchronized关键字,普通同步方法默认的锁对象是当前对象this,对于静态同步方法,锁是当前类的Class对象。 public synchronized void test2(){ //方法体 } 1.2 同步方法块 用关键字synchronized修饰可能存在线程不安全的代码块,锁对象是我们指定的引用类型的对象,基本类型不能作为锁。 synchronized(锁对象){ //可能存在线程不安全的代码 } 1.3 以售票讲解线程同步 public class SynDemo01 { /** * @param args */ public static void main(String[] args) { //真实角色 Web12306 web= new Web12306(); //代理 Thread t1 =new Thread(web,"路人甲"); Thread t2 =new Thread(web,"黄牛已"); Thread t3 =new Thread(web,"攻城师"); //启动线程 t1.start(); t2.start(); t3.start(); } } /** *

java并发编程之四、互斥

只谈情不闲聊 提交于 2020-02-01 00:56:15
前面说了并发任务之间的分工和协作,现在说并发任务之间同样很重要,甚至更重要的一个方面,互斥。因为分工、协作和互斥这三个方面,从重要性上来讲,或许可以三分天下,但从复杂性和可探讨性来讲,互斥显然更胜一筹,对互斥的深入使用,更加体现了一个人的并发编程能力。 互斥,即同一时间只能有一个并发任务可以对数据的进行访问。大多数编程语言在这里都使用的锁机制,java自然也不例外,当然java中提供了多种互斥机制,不过是锁的不同实现。 一、Synchronized synchronized可以说是java中所最为人知的互斥机制,synchronized关键字既可以用来修饰方法,也可以用来修饰代码块,通过synchronized关键字,编译器会相应的在方法或代码块的前后自动加上加锁lock()和解锁unlock(),这样无需手工加锁,也保证了加解锁的成对出现。 另外,需要注意的是,加锁,总是要锁在一个对象上,那么synchronized关键字所加锁的对象是什么了? * 修饰静态方法,这时候加锁的对象是当前类的Class对象,也可以用synchronized(A.class)来显示实现,不过这样就要小心,所有对这个类的访问可能都需要加解锁,是否你真的是想这样。 * 修饰非静态方法,这时候加锁的对象是当前类的实例对象,也可以用synchronized(this)来显式实现,同样要小心

关于static synchronized与synchronized

徘徊边缘 提交于 2020-01-31 07:24:09
1.示例题目 pulbic class Something(){ public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} } 那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢 a. x.isSyncA()与x.isSyncB() b. x.isSyncA()与y.isSyncA() c. x.cSyncA()与y.cSyncB() d. x.isSyncA()与Something.cSyncA() a,都是对同一个实例的synchronized域访问,因此不能被同时访问 b,是针对不同实例的,因此可以同时被访问 c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与 Something.isSyncB()了,因此不能被同时访问。 那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。 2

Java synchronized的原理解析

半城伤御伤魂 提交于 2020-01-31 04:05:08
开始 类有一个特性叫封装,如果一个类,所有的field都是private的,而且没有任何的method,那么这个类就像是四面围墙+天罗地网,没有门。看起来就是一个封闭的箱子,外面的进不来,里面的出不去,一般来说,这样的类是没用的。 现在为这个类定义一个public的method,这个method能够修改这个类的field,相当于为这个箱子开了一个门。门有了,然后访问者就有了,当一个时间段,有多个访问者进来,就可能会发生并发问题。 并发问题是个什么问题?最经典的例子就是转账,一个访问者从账户A扣取一部分金额,加到账户B上。在A账户扣取之后,B账户转入之前,数据处于不一致的状态,另一个访问者如果在这个时候访问B账户,获取的数据就是有问题的。这就是并发问题,导致这个问题的出现基于2个条件:1.访问者的操作导致数据在一段时间内是不一致的;2.可以有多个访问者同时操作。如果能够破坏其中一个条件,就可以解决并发问题了。我们的关注点是在第2个条件上。 回到那个箱子,回到那个门。我们设想为这个门加一把锁,一个访问者进了这个门,就上锁,期间其他访问者不能再进来;等进去的访问者出来,锁打开,允许另一个访问者进去。 1. 给一个代码块上锁 synchronized可以上锁、解锁。但是它本身并不是锁,它使用的锁来自于一个对象: 任何对象实例都有一把内部锁,只有一把 。

Java并发67问

守給你的承諾、 提交于 2020-01-31 04:00:54
1. 并发和并行 2. 进程和线程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。 而在多个进程之间切换的时候,需要进行上下文切换。但是上下文切换势必会耗费一些资源。于是人们考虑,能不能在一个进程中增加一些“子任务”,这样减少上下文切换的成本。比如我们使用Word的时候,它可以同时进行打字、拼写检查、字数统计等,这些子任务之间共用同一个进程资源,但是他们之间的切换不需要进行上下文切换。 在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程。 随着时间的慢慢发展,人们进一步的切分了进程和线程之间的职责。 把进程当做资源分配的基本单元,把线程当做执行的基本单元,同一个进程的多个线程之间共享资源 3. 类变量,成员变量和局部变量 Java中共有三种变量,分别是类变量、成员变量和局部变量。他们分别存放在JVM的方法区、堆内存和栈内存中 public class Variables { /** * 类变量 */ private static int a ; /** * 成员变量 */ private int b ; /** * 局部变量 * @param c */ public

[Android Pro] synchronized与static synchronized 的区别

本秂侑毒 提交于 2020-01-31 02:02:54
reference to : http://www.cnblogs.com/shipengzhi/articles/2223100.html 1.synchronized与static synchronized 的区别 synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。那么static synchronized恰好就是要控制类的所有实例的访问了,static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码快。实际上,在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,改类也就有一个监视快,放置线程并发访问改实例synchronized保护快,而static synchronized则是所有该类的实例公用一个监视快了,也也就是两个的区别了,也就是synchronized相当于 this.synchronized,而 static synchronized相当于Something.synchronized. 一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子: pulbic class Something(){ public synchronized void isSyncA(){

Java复习——基础知识

烈酒焚心 提交于 2020-01-31 00:56:28
对于 作者曹胜欢的专栏:Java程序员从笨鸟到菜鸟 https://blog.csdn.net/csh624366188/category_9260964.html?utm_source=zlmf2019 基本小结 基础知识 Java以;结尾。 Java的注释有 : // 行注释 /* / 一行或多行注释 / * */ javadoc 注释 Java合法命名规范 : 大小写字母或者美元符号或者下划线开头,不能以数字开头,不能用关键字。类名一般大写开头,变量和方法一般小写开头。 Java的基本数据类型 :byte字节(8位)1字节 、boolean布尔(1位)、char字符(16位)两字节、short短整型(16位)两字节、int整形(32位)4字节、long长整型(64位)8字节、float单精度浮点型(32位)、double双精度浮点型(64位) Java的特殊引用类型 : String 引用类型 :引用类型是一个对象类型的,他的值指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。 定义变/常量和变量的初始化 :常量需要用final 修饰 ,约定常量 一般全部使用大写字母。 switch运算符 : switch (expr) expr 必须是与int类型兼容的类型,即为byte,short,char,int其中的一个。 流程跳转语句-break

java 锁机制

喜欢而已 提交于 2020-01-30 21:21:12
公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁(实现秒杀的一种解决方案) (select * from product p where p.type=’xxxxx’ for update) 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计, 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁的顺序并不按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。 对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。 对于Synchronized而言,也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度,所以并没有任何办法使其变成公平锁。 AQS 的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。 CLH (Craig,Landin,and Hagersten)队列是一个虚拟的双向队列

synchronized关键字(一)

不打扰是莪最后的温柔 提交于 2020-01-30 19:23:04
多线程是应对复杂工作,提高工作效率的重要方式。其中涉及到很多的多线程的关键字,synchronized关键字是接触的比较早的一个,做个整理,方便理解。 在java中synchronized关键字是同步锁,依赖于对象存在的。每一个对象有且仅有一个同步锁,当调用某对象的synchronized关键字时,就获得了该对象的同步锁。 synchronized关键字的原理 Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁的本质是依赖于操作系统底层的操作系统的互斥锁来实现的。而操作系统实现线程间的切换就需要从用户态切换到核心态,成本非常高。这也是synchronized锁效率低,被称为重量级锁的原因。但是在jdk1.6之后,对synchronized做了很多优化,现在也已经越来越好用了。 synchronized关键字的特性 synchronized是一个互斥锁,也是一个不公平锁。锁定的是一个对象。打比方说就是只有一个马桶(对象),门上有把锁,有3个人想上厕所(线程抢占),看谁先抢到,谁先上厕所。 synchronized是可重入锁。什么是可重入锁?可重入锁在我看来类似于一个计数器,同一个线程的下,加了synchronized关键字的方法m1,m2可以相互调用而不发生死锁。 synchronized关键字的几种用法是等同的,例子如下: 1.

Java演示死锁代码

五迷三道 提交于 2020-01-30 09:34:43
死锁代码 public class DeadLock { final Object lockA = new Object(); final Object lockB = new Object(); public static void main(String[] args) { DeadLock demo = new DeadLock(); demo.startLock(); } public void startLock() { ThreadA a = new ThreadA(lockA, lockB); ThreadB b = new ThreadB(lockA, lockB); // start threads a.start(); b.start(); }}class ThreadA extends Thread { private Object lockA = null; private Object lockB = null; public ThreadA(Object a, Object b) { this.lockA = a; this.lockB = b; } public void run() { synchronized (lockA) { System.out.println("*** Thread A: ***: Lock A"); try { sleep