java中Synchronized用法介绍

synchronized关键字介绍

java提供关键字synchronized用来防止多个线程对同一临界区进行访问时,产生的资源冲突。要解决资源冲突就要引入一个锁的概念,
所有的对象都含有单一的锁,。
synchronized可以用来修饰非静态方法

public synchronized void a(){
    *******
};

修饰同步代码块

public synchronized void a(){
    synchronized(this){
        *******     
    }
};

你可以把可能在多线程访问下发生冲突的代码段放到,同步代码块中,而不是修饰整个函数,被synchronized修饰的方法是很影响多线程性能的,虽然保证了程序的正确运行,更推荐使用同步代码块。同步代码块需要一个Object的参数,表示谁获取了这个Object的对象锁,那个线程就能运行这段代码块的内容,其他线程将会阻塞,如果参数为this就表示获取的是当前对象的锁。
当多个线程调用同一个对象中被synchronized修饰的某一个方法时,该对象都会被加锁,该对象的其他被synchronized修饰的方法只有等到该方法执行完后,对象的锁被释放后才有可能获得执行的机会(只针对于其他线程而言无法调用别的被synchronized修饰的方法,当前线程可以

package com.thread.study;

class A {
    public synchronized void a() {
        System.out.println(" i am a synchronized  static function");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println("release the lock");
    }

    public synchronized void b() {
        System.out.println(" try get lock");
    }
}

public class SynchronizedTest {
    public static void main(String[] args) {
        A a = new A();
        Thread one = new Thread(new Runnable() {
            public void run() {

                a.a();
            }
        });
        one.start();
        Thread two = new Thread(new Runnable() {

            public void run() {

                a.b();
            }
        });
        two.start();
    }
}

2个线程分别调度a对象中的a()方法和b()方法,a()运行时会沉睡5秒,使用Thread.sleep()方式,不会释放锁,而调用wait()方法是当前线程会释放锁,然后进入阻塞状态。当a()被one线程运行时,试图运行b()方法的线程阻塞至one线程运行完。结果如下
这里写图片描述

synchronized 修饰静态的方法和修饰类

public synchronized static void a(){
    *******
};
public synchronized A(){
    *******
};

静态的方法是直接和类挂钩的,当调用被synchronized修饰的静态方法,当一个线程调用其中的一个静态方法时,其他线程试图调用该类的该静态方法或其他静态方法时都会被阻塞,让我们修改一下上面的例子

    package com.thread.study;

class A {
    public synchronized static void a() {
        System.out.println(" i am a synchronized  static function");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println("release the lock");
    }

    public synchronized  static void b() {
        System.out.println(" try get lock");
    }
}

public class SynchronizedTest {
    public static void main(String[] args) {
        A a = new A();
        Thread one = new Thread(new Runnable() {
            public void run() {

                A.a();
            }
        });
        one.start();
        Thread two = new Thread(new Runnable() {

            public void run() {

                A.b();
            }
        });
        two.start();
    }
}

结果这里写图片描述
是一样的,但是如果b()方法如果不是静态的,two线程访问时不会被阻塞,

    package com.thread.study;

class A {
    public synchronized static void a() {
        System.out.println(" i am a synchronized  static function");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println("release the lock");
    }

    public synchronized  void b() {
        System.out.println(" try get lock");
    }
}

public class SynchronizedTest {
    public static void main(String[] args) {
        A a = new A();
        Thread one = new Thread(new Runnable() {
            public void run() {

                A.a();
            }
        });
        one.start();
        Thread two = new Thread(new Runnable() {

            public void run() {

                a.b();
            }
        });
        two.start();
    }
}

结果如下
这里写图片描述
因为static 的a()方法是和类绑定的,而b方法是和对象a绑定的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值