同步锁分类

对象锁(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. SciPy和Numpy处理能力

    1.SciPy和Numpy的处理能力: numpy的处理能力包括: a powerful N-dimensional array object N维数组: advanced array slicing ...

  2. VTK资料收集

    使用Qt Creator开发VTK 原文链接:http://blog.csdn.net/numit/article/details/10200507 VTK应用系列:非常强大!非常善良 05-VTK在 ...

  3. CImage类的使用介绍!

    链接参考:http://www.cnblogs.com/juncheng/articles/1600730.html CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG.GIF. ...

  4. js页面传值,cookie

    // 获取页面穿值 function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + " ...

  5. window环境下,提升工作效率

    效率工具 windows桌面程序 Listary 本地文件搜索器 有道词典 划词翻译, 并且能够存在生词本里面 印象笔记 浏览资料整理 chrom插件 crxMouse 鼠标手势 chrome vim ...

  6. (转)Bootstrap 之 Metronic 模板的学习之路 - (7)GULP 前端自动化工具

    https://segmentfault.com/a/1190000006738327 初步了解 Metronic 的结构和应用后,我们就可以在项目中应用起来了.考虑到实际项目应用时,会有很多文件需要 ...

  7. Java中Scanner类的使用

    一个可以解析基本类型和字符串的简单文本扫描器. 例如,以下代码使用户能够从 System.in 中读取一个数: public class ApiScanner { public static void ...

  8. MongoDB_基础知识

    mongoDB术语:database-数据库,collection-数据库表/集合,document-数据记录行/文档,field-数据字段/域,index-索引,primary key-主键(Mon ...

  9. 记Spring搭建功能完整的个人博客「Oyster」全过程[其一] 整体思路:需求、架构及技术要求

    一两个星期前正在了解Linux内核,看得有点累,突然想趁着五一放假写个博客学学spring. 由于没有在一开始下定决心写这个博客系统,所以我又没记录一开始的分析过程.这都是写了一个星期之后的思路了. ...

  10. 自学python到找到工作的心得

    先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...