多线程知识------synchronized

  1. synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
  2. synchronized取得的锁都是对象;每个对象只有一个锁(lock)与之相关联;实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
  3. 实际上,如果在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,该类也就有一个监视块,监视线程并发访问改实例synchronized保护块。而static synchronized则是该类的所有实例公用一个监视块,静态同步方法和非静态同步方法持有的是不同的锁,前者是类锁,后者是对象锁这便是两个的区别了

一、synchronized的5种用法:

1.方法声明时使用,线程获得的是成员锁.

2.对某一代码块使用,synchronized后跟括号,括号里是变量,线程获得的是成员锁.

3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.

4.synchronized后面括号里是类,此时,线程获得的是对象锁.

5、方法静态是class锁,非静态是实例对象锁

 

synchronized作为修饰符锁方法

 二、synchronized锁重入

关键字synchronized拥有锁重入的功能。所谓锁重入的意思就是:当一个线程得到一个对象锁后,再次请求此对象锁时时可以再次得到该对象的锁的

public class ThreadDomain16

{

    public synchronized void print1()

    {

        System.out.println("ThreadDomain16.print1()");

        print2();

    }

   

    public synchronized void print2()

    {

        System.out.println("ThreadDomain16.print2()");

        print3();

    }

   

    public synchronized void print3()

    {

        System.out.println("ThreadDomain16.print3()");

    }

}

public class MyThread16 extends Thread

{

    public void run()

    {

        ThreadDomain16 td = new ThreadDomain16();

        td.print1();

    }

}

public static void main(String[] args)

{

    MyThread16 mt = new MyThread16();

    mt.start();

}

看一下运行结果:

ThreadDomain16.print1()

ThreadDomain16.print2()

ThreadDomain16.print3()

这种锁重入的机制,也支持在父子类继承的环境中

三、异常自动释放锁

当一个线程执行的代码出现异常时,其所持有的锁会自动释放。模拟的是把一个long型数作为除数,从MAX_VALUE开始递减,直至减为0,从而产生ArithmeticException

 

猜你喜欢

转载自blog.csdn.net/q1035331653/article/details/90213638