Synchronized的三种写法

本文详细介绍了Java中的`synchronized`关键字,包括其作为同步代码块、实例方法和静态方法的三种使用方式。通过示例代码展示了`synchronized`如何实现线程同步,确保资源的安全访问。同时,文章分析了对象锁与类锁的区别,帮助读者更好地理解和应用`synchronized`进行多线程控制。
Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

文章目录

  • 前言
  • 一、synchronized是什么
  • 二、synchronized的三种写法
    • 1、同步代码块
    • 2、在实例方法上使用synchronized
    • 3、在静态方法上使用synchronized
  • 总结





前言

总结一下自己在学习Synchronized 以及它的三种写法。

一、synchronized是什么?

synchronized是由JVM实现的一种互斥同步的一种方式,被synchronized修饰过的程序块在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。

如果这个方法使用了synchronized的时候,代表它加上了锁,运行此方法的时都要检查它有没有被其他线程正在使用(或者该类的其他同步方法),有的话要等它使用完,没有的话则直接锁定调用者,然后直接运行。它包括两种用法:synchronized方法和synchronized块。



二、synchronized的三种写法




1、同步代码块

代码如下(示例):

package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc=new MyClass();
        
        Thread t1=new MyThread(mc);
        Thread t2=new MyThread(mc);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠五秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}
doOther方法执行的时候不需要等待被修饰过的doSome方法结束,因为doOther方法没有被synchronized修饰,所以它不用排队等待。 

2、在实例方法上使用synchronized

代码如下(示例):

package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc=new MyClass();
        
        Thread t1=new MyThread(mc);
        Thread t2=new MyThread(mc);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠五秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}
在两个方法前都加上synchronized修饰,doOther方法执行的时候需要等待doSome方法结束完之后才执行doSome,因为锁被doSome占了,所以要排队等待。 
我们再开启一个线程:package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        //开启两个线程
        MyClass mc1=new MyClass();
        MyClass mc2=new MyClass();
        
        Thread t1=new MyThread(mc1);
        Thread t2=new MyThread(mc2);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠5秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}doOther方法执行的时候不需要等待doSome方法结束,因为MyClass对象是两个,两把锁,互不干涉。 

3、在静态方法上使用synchronized

package com.demo;


public class Demo {
    public static void main(String[] args) throws InterruptedException {
        //开启两个线程
        MyClass mc1=new MyClass();
        MyClass mc2=new MyClass();
        
        Thread t1=new MyThread(mc1);
        Thread t2=new MyThread(mc2);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized static void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠5秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized static void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}

doOther方法执行的时候不需要等待doSome方法结束,因为静态方法是类锁,不管创建了几个对象,类锁只有一把。





总结

对象锁:1个对象1把锁,100个对象有100把锁。

类锁:100个对象,全部都是这一把锁。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值