Synchronized的学习

Synchronized

Synchronized 作用:能够保证在同一时刻最多只有一个线程执行该段代码,以保证并发安全的效果。

对象锁:

包括方法锁(默认锁对象为this当前的实列对象)和同步代码块锁(自己指定锁对象)

 

代码块形式:手动指定锁对象

方法锁形式:synchronized 修饰普通的方法,锁对象默认为this

 

代码块形式:


/**

 * 对象锁实列yi,代码块形式

 */

public class SychronizedObjectCodeBlock2  implements Runnable{



   static SychronizedObjectCodeBlock2 installce = new SychronizedObjectCodeBlock2();



    public static void main(String[] args) {

        Thread t1 = new Thread(installce);

        Thread t2 = new Thread(installce);

        t1.start();

        t2.start();

        while (t1.isAlive() || t2.isAlive()){



        }

        System.out.println("Finshed");

    }



    Object lock = new Object();

    Object lock2 = new Object();

    @Override

    public void run() {

        synchronized (lock) {

            System.out.println("我是对象锁的代码块形式llock,我叫" + Thread.currentThread().getName());

            try {

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName() + "运行完毕");

        }



        synchronized (lock2) {

            System.out.println("我是对象锁的代码块形式lock2,我叫" + Thread.currentThread().getName());

            try {

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName() + "运行完毕");

        }

    }

}

 

方法锁:

/**

 * 方法锁实例

 */

public class SychronizedObjectMethod2 implements Runnable{

    static  SychronizedObjectMethod2 installce = new SychronizedObjectMethod2();

    public static void main(String[] args) {

        Thread t1 = new Thread(installce);

        Thread t2 = new Thread(installce);

        t1.start();

        t2.start();

        while (t1.isAlive() || t2.isAlive()){



        }

        System.out.println("Finshed");

    }

    @Override

    public void run() {

        methods();

    }

    public synchronized void methods()  {

        System.out.println("我是对象锁的方法修饰形式,我叫"+Thread.currentThread().getName());

        try {

            Thread.sleep(300);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        System.out.println(Thread.currentThread().getName()+"运行结束");

    }

}

 

类锁:

指synchronized 修饰的静态方法或者指定锁为class 对象。

概念:JAVA可能有很多个对象,但只有1个class 对象

形式1 :synchronized 加在static 方法上

形式二:synchronized(*.class) 代码块

概念:只有一个class对象:java类可能又很多个对象,但只有一个class对象

本质:所以所谓的类锁,不过是class对象锁而已

用法和效果:类锁只能在同一时刻被一个对象所拥有

形式一:

 

/**
 *
类锁的第一种形式 ,static 形式
 */

public class SychronizedClassStatic4  implements  Runnable{
   
static  SychronizedClassStatic4 instance1 =new SychronizedClassStatic4();
    static 
SychronizedClassStatic4 instance2 =new SychronizedClassStatic4();
   
@Override
   
public void run() {
        methods()
;
   
}
   
public static  synchronized void methods() {
        System.
out.println("我是类锁的d第一种形式:static 。我叫" + Thread.currentThread().getName());
        try
{
            Thread.sleep(
300);
       
} catch (InterruptedException e) {
            e.printStackTrace()
;
       
}
        System.
out.println(Thread.currentThread().getName()+"运行结束");
   
}
   
public static void main(String[] args) {
        Thread t1 =
new Thread(instance1);
       
Thread t2 = new Thread(instance2);
       
t1.start();
       
t2.start();
        while
(t1.isAlive() || t2.isAlive()){

        }
        System.
out.println("Finshed");

   
}
}

 形式二:

/**

 *

 */

public class SychronizedClassClass implements Runnable{



    static  SychronizedClassClass instance1 =new SychronizedClassClass();

    static  SychronizedClassClass instance2 =new SychronizedClassClass();

    @Override

    public void run() {

        method();

    }

    public void method(){

        synchronized (SychronizedClassClass.class){

            System.out.println("我是类锁的第二种形式(*.class)。我叫"+Thread.currentThread().getName());

            try {

                Thread.sleep(300);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName()+"运行结束");

        }

    }

    public static void main(String[] args) {

        Thread t1 = new Thread(instance1);

        Thread t2 = new Thread(instance2);

        t1.start();

        t2.start();

        while (t1.isAlive() || t2.isAlive()){



        }

        System.out.println("Finshed");



    }

}

面试易问问题:

  1. 两个线程同时访问一个对象的同步方法。
  2. 两个线程访问的是两个对象的同步方法。
  3. 两个线程访问的是synchronized的静态方法。
  4. 同时访问同步方法与非同步方法。(非同步方法不受影响)
  5. 访问同一个对象的不同的普通同步方法。
  6. 同时访问静态synchronize的非静态的synchronized方法。
  7. 方法抛出异常,会释放锁’

核心思想:

  1. 一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应上面的1,5);
  2. 每个实列都对应有自己的一把锁不同实列互不影响;列外:锁对象是 *.class以及sychronizde修饰的是static 方法的时候,所有对象·共用同意把锁(对应2,3,4,6中情况);
  3. 无论是方法正常执行完毕还是方法抛出异常,都是释放锁(对应第7中情况)

4.补充:synchronized方法里用了没被synchronized修饰的方法,是不线程安全的

性质:

  1. 可重入,2 不可中断 ,

可重入:可重入是指同一个线程的外层函数获得锁之后,内层函数可以直接再次获取该锁;

不可重入:一个线程拿到锁了,如果需要再次使用该锁,必须先释放该锁才能再次获取

synchronized是可重入锁

可重入锁的好处:

1 避免死锁 2 提升封装性

粒度:可重入的特性是线程级别的,不是调用级别的

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值