java学习笔记之多线程同步
2016-11-24 21:47
127 查看
1、线程同步机制是为了解决多线程安全问题进入的机制。
同步代码块
synchronized(对象) //这个对象可以是任意的对象
{
需要被同步的代码
}
同步代码块解决多线程安全问题的原理:对象可以看做是一个锁,线程1进入执行被同步的代码的时候带有锁,另一个线程2想要执行的时候会去判断锁,线程1持有锁,因此线程2无法执行被同步的代码,当线程1结束,就释放锁,其他线程才可以执行被同步的代码--------->这是我自己的理解。。。
综上,同步的是指就是在目前的情况下保证了一次只能有一个线程在执行,其他线程无法执行,这就是同步的锁机制。
弊端:降低效率(因为每次都要判断锁)
2、有可能出现一种情况:多线程安全问题出现后,加入了同步机制,依旧有安全问题,这时,可能是没有遵守同步的前提
同步的前提:多个线程在同步中,必须使用同一个锁,这才是多个线程同步。
例如:synchronized(new Object):每次线程来判断的时候都会new一个对象,每个线程持有的锁都不一样,就会导致加了同步之后依旧有安全问题
多线程是并发访问,那么加了同步之后是否违背了并发访问:不是,因为被同步的代码需要被执行代码的一部分,并不是全部。
3、当函数中的所有代码都需要同步之后,这个时候引入同步函数的概念
将同步synchronized当做一个修饰符
public synchronized void add(int n){
~~~~~~~~~
}
因此同步的表现形式有两种:1、同步代码块 2、同步函数
那么同步函数使用的锁是什么呢?--->是当前调用该函数的对象,this
如果同步函数被静态修饰后,
public static synchronized void add(int n){
~~~~~~~~~
}
由于静态函数不需要对象,所以不持有this关键字,所有它的锁不是this。字节码文件(.class)会在堆中产生一个字节码文件对象,且是唯一的。字节码文件对象的表示方式 类名.class
4、同步函数与同步代码块的区别
同步代码块可以使用任意的对象作为锁,同步函数只能使用this作为锁
当一个类中如果需要多个锁,还有多个类中使用一个锁,这时就需要同步代码块来完成。因此建议更多的使用同步代码块。
5、死锁
是多线程加了同步之后的一个弊端。
死锁原因之一:由于锁之间的嵌套,容易引起死锁,因此开发的时候,尽量避免同步嵌套
public static synchronized void add(int n){
synchronized(对象){
~~~~~~~~
}
}
面试题曾经出过如何写出一个死锁程序。可以写一个同步嵌套的程序。
public class myLock {
public static final Object LOCK1 = new Object();
public static final Object LOCK2 = new Object();
}
public class lockDemo implements Runnable{
private boolean flag;
lockDemo(boolean flag){
this.flag=flag;
}
public void run(){
if(flag){
synchronized(myLock.LOCK1){
System.out.println("if---LOCK1");
synchronized(myLock.LOCK2){
System.out.println("if---LOCK2");
}
}
}
else{
synchronized(myLock.LOCK2){
System.out.println("else---LOCK2");
synchronized(myLock.LOCK1){
System.out.println("else---LOCK2");
}
}
}
}
}
public class deadLock {
public static void main(String[] args) {
lockDemo locka=new lockDemo(true);
lockDemo lockb=new lockDemo(false);
new Thread(locka).start();
new Thread(lockb).start();
System.out.println("over");
}
}
·
同步代码块
synchronized(对象) //这个对象可以是任意的对象
{
需要被同步的代码
}
同步代码块解决多线程安全问题的原理:对象可以看做是一个锁,线程1进入执行被同步的代码的时候带有锁,另一个线程2想要执行的时候会去判断锁,线程1持有锁,因此线程2无法执行被同步的代码,当线程1结束,就释放锁,其他线程才可以执行被同步的代码--------->这是我自己的理解。。。
综上,同步的是指就是在目前的情况下保证了一次只能有一个线程在执行,其他线程无法执行,这就是同步的锁机制。
弊端:降低效率(因为每次都要判断锁)
2、有可能出现一种情况:多线程安全问题出现后,加入了同步机制,依旧有安全问题,这时,可能是没有遵守同步的前提
同步的前提:多个线程在同步中,必须使用同一个锁,这才是多个线程同步。
例如:synchronized(new Object):每次线程来判断的时候都会new一个对象,每个线程持有的锁都不一样,就会导致加了同步之后依旧有安全问题
多线程是并发访问,那么加了同步之后是否违背了并发访问:不是,因为被同步的代码需要被执行代码的一部分,并不是全部。
3、当函数中的所有代码都需要同步之后,这个时候引入同步函数的概念
将同步synchronized当做一个修饰符
public synchronized void add(int n){
~~~~~~~~~
}
因此同步的表现形式有两种:1、同步代码块 2、同步函数
那么同步函数使用的锁是什么呢?--->是当前调用该函数的对象,this
如果同步函数被静态修饰后,
public static synchronized void add(int n){
~~~~~~~~~
}
由于静态函数不需要对象,所以不持有this关键字,所有它的锁不是this。字节码文件(.class)会在堆中产生一个字节码文件对象,且是唯一的。字节码文件对象的表示方式 类名.class
4、同步函数与同步代码块的区别
同步代码块可以使用任意的对象作为锁,同步函数只能使用this作为锁
当一个类中如果需要多个锁,还有多个类中使用一个锁,这时就需要同步代码块来完成。因此建议更多的使用同步代码块。
5、死锁
是多线程加了同步之后的一个弊端。
死锁原因之一:由于锁之间的嵌套,容易引起死锁,因此开发的时候,尽量避免同步嵌套
public static synchronized void add(int n){
synchronized(对象){
~~~~~~~~
}
}
面试题曾经出过如何写出一个死锁程序。可以写一个同步嵌套的程序。
public class myLock {
public static final Object LOCK1 = new Object();
public static final Object LOCK2 = new Object();
}
public class lockDemo implements Runnable{
private boolean flag;
lockDemo(boolean flag){
this.flag=flag;
}
public void run(){
if(flag){
synchronized(myLock.LOCK1){
System.out.println("if---LOCK1");
synchronized(myLock.LOCK2){
System.out.println("if---LOCK2");
}
}
}
else{
synchronized(myLock.LOCK2){
System.out.println("else---LOCK2");
synchronized(myLock.LOCK1){
System.out.println("else---LOCK2");
}
}
}
}
}
public class deadLock {
public static void main(String[] args) {
lockDemo locka=new lockDemo(true);
lockDemo lockb=new lockDemo(false);
new Thread(locka).start();
new Thread(lockb).start();
System.out.println("over");
}
}
·
相关文章推荐
- Java学习笔记---多线程同步的五种方法
- Java学习笔记---多线程同步的五种方法
- Java学习笔记---多线程同步的五种方法
- Java学习笔记---多线程同步的五种方法
- [学习笔记]JAVA的多线程同步编程(非OOP)
- Thinking in Java学习笔记(三)(zt)
- 我的Thinking in Java学习笔记(四) (zt)
- 我的Thinking in Java学习笔记(1)
- 我的Thinking in Java学习笔记(2)
- java对象序列化学习笔记
- Java中文处理学习笔记
- JAVA与模式 学习笔记(一) 统一的建模语言UML介绍(2)
- Java中文处理学习笔记——Hello Unicode
- 我的Thinking in Java学习笔记(九)
- JAVAGUIDE(学习笔记1)
- java对象序列化学习笔记(z)
- 我的Thinking in Java学习笔记(六)(zt)
- JAVA学习笔记之JIRA
- JAVA与模式 学习笔记(一) 统一的建模语言UML介绍(2)
- 我的Thinking in Java学习笔记(四)