java多线程(五)synchronized关键字修饰代码块

转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/47916703

在上一篇博客中我们介绍了synchronized关键字修饰方法的用法,我们接着介绍synchronized关键字。除了修饰方法之外,还可以修饰代码块,一共有以下5种用法。

一、this

synchronized(this){
    //互斥代码
}

这里的this指的是执行这段代码的对象,synchronized得到的锁就是this这个对象的锁,这种写法等价于我们上一篇博客中讨论的:

public synchronized void func(){
    //互斥代码
}

二、A.class

synchronized(A.class){
    //互斥代码
}

这里A.class得到的是A这类,所以synchronized关键字得到的锁是类的锁,这种方法同下面的方法功能是相同的:

public static synchronized void fun(){
    //互斥代码
}

所有需要类的锁的方法等不能同时执行,但是它和需要某个对象的锁的方法或者是不需要任何锁的方法可以同时执行。

三、object.getClass()

synchronized(object.getClass){
    //互斥代码
}

这种方法一般情况下同第二种是相同,但是出现继承和多态时,得到的结果却是不相同的。所以一般情况下推荐使用A.class的方式。

四、object

synchronized(object){
    //互斥代码
}

这里synchronized关键字拿到的锁是对象object的锁,所有需要这个对象的锁的方法都不能同时执行。

public class Trans {
private Object lock = new Object();

    public void printNum(int num){
        synchronized (lock) {
            System.out.print(Thread.currentThread());
            for(int i=0;i<25;i++){
                System.out.print(i+" ");
            }
            System.out.println();
        }
    }

}
class MyThread implements Runnable {
    private Trans trans;
    private int num;  

    public MyThread(Trans trans, int num) {
        this.trans = trans;
        this.num = num;
    }  

    public void run() {
        while (true)
        {
            trans.printNum(num);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }  

    }
}

public class Test {  

    public static void main(String[] args) {  

        Trans t = new Trans();
        Trans t1 = new Trans();
        Thread a = new Thread(new MyThread(t, 1));
        Thread b = new Thread(new MyThread(t1, 2));  

        a.start();
        b.start();  

    }  

}

在上边的例子中试图使用这种方法达到互斥方法打印方法,但是事实是这样做是没有效果的,因为每个Trans对象都有自己的Object对象,这两个对象都有自己的锁,所以两个线程需要的是不同锁,两个锁之间没有任何相互作用,所以不会起到互斥作用。

五、static object

上边的代码稍作修改就可以起到互斥作用,将Trans类中Object对象的声明改为下面这样:

private static Object lock = new Object();

这样不同的类使用的就是同一个object对象,需要的锁也是同一个锁,就可以达到互斥的效果了。

经过两篇博客的介绍,我们详细的讨论了synchronized关键字的用法,看似非常复杂,其实抓住要点之后还是很好区分的,只要看synchronized获得的是哪个对象或者类的锁就行啦,其他需要这个锁的方法都不能同时执行,不需要这个锁的方法都能同时执行。

最后还要告别一个误区,相信大家都不会再犯这种错误了,synchronized锁住的是一个对象或者类(其实也是对象),而不是方法或者代码段。

版权声明:本文为博主原创文章,转载请注明出处,查看原文章,请访问:http://blog.csdn.net/xingjiarong

时间: 2024-11-12 17:55:28

java多线程(五)synchronized关键字修饰代码块的相关文章

Java多线程同步 synchronized 关键字的使用

代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行它包括两种用法:synchronized 方法和 synchronized 块. JAVA多线程买票案例 synchronized 同步 用synchronized 块实现同步 public static void main(String[] args) { // runable对

Java多线程:synchronized关键字和Lock

一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中foo1和foo2是SynchronizedDemo1类的两个静态方法.在不同的线程中,这两个方法的调用是互斥的,不仅是它们之间,任何两个不同线程的调用也互斥. public class SynchronizedDemo1 { public synchronized static void foo1(){} pu

Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(ReentrantLock)以及读写锁(ReentrantReadWriteLock). 1. ReentrantLock 在Java多线程(二) 多线程的锁机制 里面,已经总结过通过使用Synchronized关键字实现线程内的方法锁定.但使用Synchronized关键字有一些局限性,上锁和释放锁是由JVM决定的

java 多线程9 : synchronized锁机制 之 代码块锁

synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用synchronized同步语句块来解决问题.看一下例子: 下面例子是优化后的例子 使用代码块锁,原先例子是方法锁,就是同步 必须要执行2个for  public class ThreadDomain18 { public void doLongTimeTask() throws Exception

java学习--基础知识进阶第一天--static静态关键字、代码块

今日内容介绍 u 知识回顾 u static静态关键字 u 代码块 第1章 知识回顾 1.1 方法的回顾 1.1.1 案例代码一: package com.itheima_01; /* * 需求:定义一个方法求两个数的和,并在主方法中调用 * * 方法:类中的一段具有特定功能的程序,提高了代码的复用性和可维护性 * 定义格式: * public static 返回值类型(没有返回值写void) 方法名(参数类型 参数名,参数类型 参数名2) {//形参 * 方法体; * } * 调用方式: *

Java中this和static关键字及代码块

this: 可以使用this表示类中的属性------this.name=name 可以使用this强调调用的是本类的方法 可以使用this调用本类的构造方法------this();调用本类中无参构造方法 可以使用this表示当前对象(调用方法的对象)----最重要的用途 static: 声明属性---------属性则为全局变量 声明方法---------Person.setName("Tom");使用类名称调用static方法 普通代码块:直接在方法或是语句中定义的代码块 pub

Java的synchronized的同步代码块和同步方法的区别

线程同步问题大都使用synchronized解决,有同步代码块和同步方法的两种方式,主要记一下这两种的区别 测试代码: 1 package com.xujingyang.testThread; 2 3 public class SynObj{ 4 public synchronized void showA(){ 5 System.out.println("showA.."); 6 try { 7 Thread.sleep(3000); 8 } catch (InterruptedEx

多线程编程-- part 3 多线程同步-&gt;synchronized关键字

多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取800,当我同时用两个线程调用这个取钱操作时,有时可以取出1600元 static class HelloRunable implements Runnable{ private int money = 1000; //取出800元 int getMoney() { System.out.print

java线程总结--synchronized关键字,原理以及相关的锁

在多线程编程中,synchronized关键字非常常见,当我们需要进行"同步"操作时,我们很多时候需要该该关键字对代码块或者方法进行锁定.被synchronized锁定的代码块,只能同时有一条线程访问该代码块. 上面是很多人的认识,当然也是我之前对synchronized关键字的浅显认识,其实上面的观点存在一定的偏差.在参考了很多文章以及自己动手测试过相关代码后,我觉得有必要记录下自己对synchronized关键字的一些理解,在这个过程,会简单说说synchronized关键字的具体