同步锁分类

对象锁(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个线程会串行执行同步锁里面的代码。

最新文章

  1. oracle表分区以及普表转分区表(转)
  2. myeclipse 无法启动
  3. 创建catalog数据库
  4. STM32学习笔记(四) RCC外设的学习和理解
  5. visual studio 2012 has stopped working
  6. 走进科学 WAF(Web Appllication Firewall)
  7. poj 1611 The Suspects 解题报告
  8. rsync 不能同不子级目录的问题
  9. Android TextView文字横向自动滚动(跑马灯)
  10. 设置浮点数的显示精度&amp;precision(0)
  11. javascript高级编程笔记01(基本概念)
  12. Source kit service terminated Editor functionality temporarily limited
  13. List&lt;string&gt; to List&lt;decimal&gt; by C# 2.0
  14. java dom4j解析xml实例(2)
  15. 最大堆(Java数组实现)
  16. 快速构建SPA框架SalutJS--项目工程目录 三
  17. 微信小程序——常用快捷键【四】
  18. spring-cloud-config-server——Environment Repository(File System Backend)
  19. 『关键点检测』CPN:Cascaded Pyramid Network for Multi-Person Pose Estimation
  20. Redis占硬盘空间

热门文章

  1. C# 5.0新加特性
  2. PLSQL 11注册码
  3. C# indexof 注意
  4. Fear No More歌词
  5. MySQL_视图/触发器/事务/存储过程/函数
  6. VMware ESXi定制版(OEM ISO)资源下载(包含5.1\5.5\6.0)
  7. 路飞学城Python-Day77
  8. Jmeter中使用CSV Data Set Config
  9. Flex简易教程
  10. js中数组常用方法