同步锁分类

对象锁(this)

类锁(类的字节码文件对象即类名.class)

字符串锁(比较特别)

应用场景

在多线程下对共享资源的安全操作。

需求:启动5个线程对共享资源total进行安全操作。

同步锁在多线程单例模式下的使用

以上三类同步锁都可以。

package cn.myThread;

public class MyThread implements Runnable {
    private static int total =
10;
    @Override
    public void run() {
        synchronized (this){ //使用this对象锁
        //synchronized (MyThread.class){ //使用MyThread.class类锁
        //synchronized (""){
//使用字符串锁
           
System.out.println(Thread.currentThread().getName()
+ "正在运行");
            try {
                Thread.sleep(100);
            } catch (InterruptedException
e) {
                e.printStackTrace();
            }
            total--;
            System.out.println(total);
            System.out.println(Thread.currentThread().getName()
+ "线程结束");
        }
    }
}

package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {
    public static void main(String[]
args){
        MyThread
myThread = new MyThread();
        Thread thread = null;
        for (int i = 1 ;
i <= 5 ; i++){
            thread = new Thread(myThread,"线程"+i);
//
开启5个线程,传入同一个对象
            thread.start();
        }
    }
}

线程1正在运行

9

线程1线程结束

线程3正在运行

8

线程3线程结束

线程5正在运行

7

线程5线程结束

线程2正在运行

6

线程2线程结束

线程4正在运行

5

线程4线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象this指向同一个的对象(同步锁对象MyThread.class类锁是同一个对象、同步锁对象 ”” 字符串锁是同一个对象),所以5个线程会串行执行同步锁里面的代码。

同步锁在多线程多例模式下的使用

错误用法

package cn.myThread;

public class MyThread implements Runnable {
    private static int total =
10;
    @Override
    public void run() {
        synchronized (this){//使用this对象锁
           
System.out.println(Thread.currentThread().getName()
+ "正在运行");
            try {
                Thread.sleep(100);
            } catch (InterruptedException
e) {
                e.printStackTrace();
            }
            total--;
            System.out.println(total);
            System.out.println(Thread.currentThread().getName()
+ "线程结束");
        }
    }
}

package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {
    public static void main(String[]
args){
        Thread thread = null;
        for (int i = 1 ; i <= 5 ;
i++){
            thread = new Thread(new MyThread(),"
线程"+i);//开启5个线程,传入5个不同对象
            thread.start();
        }
    }
}

线程2正在运行

线程1正在运行

线程3正在运行

线程5正在运行

线程4正在运行

9

7

9

8

线程1线程结束

线程5线程结束

线程2线程结束

线程3线程结束

6

线程4线程结束

分析:从运行结果可以看出5个线程并行执行同步锁里面的代码,因为5个线程中的同步锁对象this指向5个不同的对象,所以5个线程会同时执行同步锁里面的代码。

正确用法

方式一:

package cn.myThread;

public class MyThread implements Runnable {
    private static int total =
10;
    @Override
    public void run() {
       
synchronized (MyThread.class){//使用MyThread.class类锁
           
System.out.println(Thread.currentThread().getName()
+ "正在运行");
            try {
                Thread.sleep(100);
            } catch (InterruptedException
e) {
                e.printStackTrace();
            }
            total--;
            System.out.println(total);
            System.out.println(Thread.currentThread().getName()
+ "线程结束");
        }
    }
}

package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {
    public static void main(String[]
args){
        Thread thread = null;
        for (int i = 1 ;
i <= 5 ; i++){
            thread = new Thread(new MyThread(),"线程"+i);
//
开启5个线程,传入5个不同对象
            thread.start();
        }
    }
}

线程1正在运行

9

线程1线程结束

线程5正在运行

8

线程5线程结束

线程4正在运行

7

线程4线程结束

线程3正在运行

6

线程3线程结束

线程2正在运行

5

线程2线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象MyThread.class类锁是同一个对象,所以5个线程会串行执行同步锁里面的代码。

方式二:

package cn.myThread;

public class MyThread implements Runnable {
    private static int total =
10;
    @Override
    public void run() {
       
synchronized (""){//使用字符串锁
            System.out.println(Thread.currentThread().getName()
+ "正在运行");
            try {
                Thread.sleep(100);
            } catch (InterruptedException
e) {
                e.printStackTrace();
            }
            total--;
            System.out.println(total);
            System.out.println(Thread.currentThread().getName()
+ "线程结束");
        }
    }
}

package cn.test;

import cn.myThread.MyThread;

public class TestMyThread {
    public static void main(String[]
args){
        Thread thread = null;
        for (int i = 1 ;
i <= 5 ; i++){
            thread = new Thread(new MyThread(),"线程"+i);
//
开启5个线程,传入5个不同对象
            thread.start();
        }
    }
}

线程1正在运行

9

线程1线程结束

线程4正在运行

8

线程4线程结束

线程5正在运行

7

线程5线程结束

线程3正在运行

6

线程3线程结束

线程2正在运行

5

线程2线程结束

分析:从运行结果可以看出5个线程串行执行同步锁里面的代码,因为5个线程中的同步锁对象 ”” 字符串锁是同一个对象,所以5个线程会串行执行同步锁里面的代码。

java同步锁的正确使用的更多相关文章

  1. Java同步锁——lock与synchronized 的区别【转】

    在网上看来很多关于同步锁的博文,记录下来方便以后阅读 一.Lock和synchronized有以下几点不同: 1)Lock是一个接口,而synchronized是Java中的关键字,synchroni ...

  2. Java同步锁全息详解

    一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...

  3. java 同步锁方法

    方法一:动态同步锁 class Demo_thread implements Runnable{ public static int sum = 0; public synchronized void ...

  4. Java同步锁何时释放?

    在测试java多线程中有关 “生产者和消费者” 这个经典问题的时候,写代码测试的时候,思考到一些问题(所以还是要动手,实践才能储真知啊), synchronize 同步锁何时释放,何时获得?重新获得锁 ...

  5. java同步锁实现方法

    1.synchronized关键字修饰 当用此关键字修饰方法时,     内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态 synchronized关键字也可以修饰静态方法,此 ...

  6. JAVA同步锁机制 wait() notify() notifyAll()

    wait() notify() notifyAll() 这3个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块中使用. wait() 必须在synchronized函数或 ...

  7. Java Learning:并发中的同步锁(synchronized)

    引言 最近一段时间,实验室已经倾巢出动找实习了,博主也凑合了一把,结果有悲有喜,BAT理所应当的跪了,也收到了其他的offer,总的感受是有必要夯实基础啊. 言归正传,最近在看到java多线程的时候, ...

  8. Redis实现分布式锁的正确使用方式(java版本)

    Redis实现分布式锁的正确使用方式(java版本) 本文使用第三方开源组件Jedis实现Redis客户端,且只考虑Redis服务端单机部署的场景. 分布式锁一般有三种实现方式: 1. 数据库乐观锁: ...

  9. Java多线程简析——Synchronized(同步锁)、Lock以及线程池

    Java多线程 Java中,可运行的程序都是有一个或多个进程组成.进程则是由多个线程组成的.最简单的一个进程,会包括mian线程以及GC线程. 线程的状态 线程状态由以下一张网上图片来说明: 在图中, ...

随机推荐

  1. map参数值取代

    public static String processTemplate(String tpl, Map<String, ?> params){ Iterator<String> ...

  2. C# 4.0新加特性

    协变和逆变 这个在C#2.0中就已经支持委托的协变和逆变了,C#4.0开始支持针对泛型接口的协变和逆变: IList<string> strings = new List<strin ...

  3. deeplearning4j – 分布式DL开源项目

    原文链接:http://www.52ml.net/16157.html Deeplearning4j is the first commercial-grade deep learning libra ...

  4. (转)基于MVC4+EasyUI的Web开发框架经验总结(6)--在页面中应用下拉列表的处理

    http://www.cnblogs.com/wuhuacong/p/3840321.html 在很多Web界面中,我们都可以看到很多下拉列表的元素,有些是固定的,有些是动态的:有些是字典内容,有些是 ...

  5. CorelDRAW X8超低价优惠啦,你却还在用CDR X4破解?!

    最近大火的<都挺好> 已经完美收官 出于好奇,小编也正在追剧呢 同样出生在畸形的原生家庭 长大后 有钱就是苏明玉 没钱就是樊胜美 所以不要抱怨老天给了你怎样的资源 想要什么就要靠自己的双手 ...

  6. 文字左右滚动选择,改变direction的值

    1.从左到右滚动显示<marquee direction=left>测试</marquee> 2.从右到左滚动显示<marquee direction=right> ...

  7. 【转】Oracle基础结构认知——oracle内存结构 礼记八目 2017-12-15 20:31:27

    oracle的数据库实例是一组后台进程和内存结构组成的,而内存结构由系统全局区(system global area)和程序全局区(program global area)组成. #修改SGA和PGA ...

  8. Java启动问题-Application Server was not connected before run configuration stop, reason: Unable to ping server at localhost:1099

    环境一直跑的挺好的,突然报这么一个错误,百思不得其解. 网上查询之后才想起来,自己当时为了IE能运行浪潮服务器的远程console,将环境变量里面的java换成了32位版本的. 修改jre版本与环境变 ...

  9. 2015 Multi-University Training Contest 6 hdu 5357 Easy Sequence

    Easy Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  10. 仿照CIFAR-10数据集格式,制作自己的数据集

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50801226 前一篇博客:C/C++ ...