重学JAVA基础(八):锁的基本知识
1.线程状态

如上图,当我们新建一个线程,并start后,其实不一定会马上执行,因为只有操作系统调度了我们的线程,才能真正进行执行,而操作系统也随时可以运行其他线程,这时线程又回到可运行状态。这个过程是操作系统控制的,不是我们能控制的。我们能控制的是将线程变为blocked,并从blocked变为runable状态。
在以前实验的wait和notify中,我当时并没有注意到notify后会进行锁阶段,以为notify后直接进入runable状态,等待操作系统调度。 从上面的图中可以看到,我们notify后,实际现场进入了locked状态,一个线程时就直接进入runable状态了,但是在多线程的情况下,因为我们wait或者notify时都是在同步中做的,只有获得同步锁的线程才有机会进入runable,其他线程还得等待。
因此在这里主要是学习一下锁的原理
2.锁
1).内置锁
java的每个对象都可以用作一个同步锁,这个锁就是内置锁,或者监视锁,通过同步方法或者代码块获得内置锁,也就是运用synchronized关键字字
2).显示锁
jdk提供的高级锁,比如Lock、Condition等,主要用于内置锁不方便实现的功能
3.锁的一些特性
1).可重入
java线程时基于每线程计算锁的,在同一个线程中,可以再次进入该同步方法,而不会造成死锁。进入一次计数器加1,退出后减1。
/**
* 同步方法
* @author tomsnail
* @date 2015年4月18日 下午12:15:30
*/
public synchronized void test1(){
test1();
}
2).公平/非公平
在公平的情况下,所有需要获得锁的线程,都有相同几率获得锁,反之,某些线程可以优先获得锁。
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
} /**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
ReentrantLock锁的构造方法,就提供了公平/非公平的机制,而synchronized没有明确的公平/非公平性保证,因为是操作系统就行调度的。公平锁和非公平锁的具体实现和原理,以后再好好学习一下。
4.死锁
java因为是线程级别的,我借用进程的死锁:是指多个线程循环等待其他线程占用的资源而无限期的僵持下去的局面。
死锁产生的必要条件:
a).互斥条件
某个资源在一段时间内,只能由一个线程占用
b).不可抢占条件
在该资源没有被释放前,其他线程不能抢占
c).占用且申请条件
该线程已经占有一个资源,但是又申请新的资源,但要申请的资源被其他线程占用
d).循环等待条件
多个线程等待其他线程释放资源
public class DeadLockThread {
static final String a = "a";
static final String b = "b";
public static void main(String[] args) {
Thread a = new Thread(new DeadLockThread1());
Thread b = new Thread(new DeadLockThread2());
a.start();
b.start();
}
}
class DeadLockThread1 implements Runnable{
@Override
public void run() {
testb();
}
public void testa(){
synchronized (DeadLockThread.a) {
System.out.println(DeadLockThread.a);
}
}
public void testb(){
synchronized (DeadLockThread.b) {
System.out.println(DeadLockThread.b);
testa();
}
}
}
class DeadLockThread2 implements Runnable{
@Override
public void run() {
testa();
}
public void testa(){
synchronized (DeadLockThread.a) {
System.out.println(DeadLockThread.a);
testb();
}
}
public void testb(){
synchronized (DeadLockThread.b) {
System.out.println(DeadLockThread.b);
}
}
}
当上面四个条件同时满足时,就会产生死锁。
当产生死锁的时候,我们破坏掉上面的四个条件就可以了。
重学JAVA基础(八):锁的基本知识的更多相关文章
- 重学JAVA基础(七):线程的wait、notify、notifyAll、sleep
/** * 测试thread的wait notify notifyAll sleep Interrupted * @author tomsnail * @date 2015年4月20日 下午3:20: ...
- 重学JAVA基础(六):多线程的同步
1.synchronized关键字 /** * 同步关键字 * @author tomsnail * @date 2015年4月18日 下午12:12:39 */ public class SyncT ...
- 重学JAVA基础(五):面向对象
1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...
- 重学JAVA基础(二):Java反射
看一下百度的解释: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息 ...
- 重学JAVA基础(一):PATH和CLASSPATH
我想大多数Java初学者都会遇到的问题,那就是怎么配置环境,执行java -jar xxx.jar 都会报NoClassDefFindError,我在最开始学习的时候,也遇到了这些问题. 1.PAT ...
- 重学JAVA基础(四):线程的创建与执行
1.继承Thread public class TestThread extends Thread{ public void run(){ System.out.println(Thread.curr ...
- 重学JAVA基础(三):动态代理
1.接口 public interface Hello { public void sayHello(); } 2.实例类 public class Hello2 { public void sayH ...
- 重学 Java 设计模式:实战享元模式「基于Redis秒杀,提供活动与库存信息查询场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 程序员的上下文是什么? 很多时候一大部分编程开发的人员都只是关注于功能的实现,只 ...
- 12天,这本《重学Java设计模式》PDF书籍下载量9k,新增粉丝1400人,Github上全球推荐榜!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言
随机推荐
- linux运维笔记——常用命令详解diff
1.diff 你可以把diff看成是linux上的文件比对工具 例子文件内容: [root@localhost disks]# cat test1.txt a b c d [root@localhos ...
- linux 下部署 redis
Redis是一种高级key-value数据库.它跟memcached类似,不过数据 可以持久化,而且支持的数据类型很丰富.有字符串,链表,集 合和有序集合.支持在服务器端计算集合的并,交和补集(dif ...
- javascript学习第一课
1.基本知识: 1.1 词法结构 1.1.1 字符集 javascript程序是用Unicode字符集编写的. 1.1.2 区分大小写 javascript是区分大小写的语言.也即是关键字.变量.函数 ...
- Oracle primary,unique,foreign 区别,Hibernate 关联映射
Oracle primary,unique,foreign 区别 转:http://www.cnblogs.com/henw/archive/2012/08/15/2639510.html NOT N ...
- JAVA -Xms -Xmx -XX:PermSize -XX:MaxPermSize 区别
java -Xms -Xmx -XX:PermSize -XX:MaxPermSize 在做java开发时尤其是大型软件开发时经常会遇到内存溢出的问题,比如说OutOfMemoryError ...
- Javascript 添加自定义静态方法属性JS清除左右空格
例如加trim()清除左右空格 String.prototype.trim=function() { return this.replace(/(^\s*)|(\s*$)/g,''); } 调用 va ...
- 第40讲:Set、Map、TreeSet、TreeMap操作代码实战
今天来看下set map的操作,让我们从代码出发 val data = mutable.Set.empty[Int] data ++= List(1,2,3)//在空set上加入列表 data += ...
- International Conference in 2014
International Conference on Machine Learning (ICML2014, Beijing).(papers are available) Neural Infor ...
- json原理和jquey循环遍历获取所有页面元素
1.json原理: javascript object notation (javascript 对象表示法) 是一种轻量级的数据交换语言,由javascript衍生而出,适用于.NET java c ...
- 在sqlServer中把数据导出为insert脚本
有时候为了把数据导出为insert脚本,不得不用一些小工具,或者通过自己写存储过程来完成这一操作.其实SqlServer本身就有这种功能.以下是详细步骤: