Java 学习笔记 —— synchronized 用法

本文详细介绍了Java中的synchronized关键字,包括其作用、两种主要用法(对象锁和类锁),并提供了具体的代码示例来展示如何使用synchronized来保证线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.synchronized 作用

保证同一时刻只有一个线程执行某块代码, 以达到并发安全的效果.

package com.company;

public class SynchronizeTest2 implements  Runnable {
    public  static SynchronizeTest2 test = new SynchronizeTest2();

    static int a = 0;
    @Override
    public void run() {
        //synchronized (this){
            System.out.println("线程开始, 名称: " + Thread.currentThread().getName());

            for(int j=0;j<10000;j++){
                a ++;
            }

            System.out.println("线程结束, 名称: " + Thread.currentThread().getName());
       // }
    }

    public static void main(String args[]) throws InterruptedException{
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test); 
        t1.start();
        t2.start(); 
        System.out.println((t1.getState()));
        System.out.println((t2.getState())); 
        t1.join();
        t2.join();
        System.out.println(a);
        System.out.println("线程结束");
    }
}

变量a加一分为三步, 从内存中取a原值、给a加1、存入内存, 所以当多个线程并发去给a执行自加的时候, 就会出现问题. a最后的结果就会小于预期值20000.
如果run方法中的代码块有synchronized 修饰, 则a的自加过程在同一时刻只有一个线程执行, 保证了串行执行, a最后的值就会达到预期值20000

2. synchronized 两种用法

对象锁, 包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)

类锁, synchronized修饰的静态方法或指定锁为class对象

细分为4种

1) 对象锁 -> 普通方法锁
public class SynchronizedTest3 implements Runnable{

    //  普通方法锁
    @Override
    public void run() {
        method();
    }

    public synchronized void method() { //  普通方法锁
        System.out.println("线程开始: " + Thread.currentThread().getName());
        try{
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("线程结束: "+ Thread.currentThread().getName());
    }

    public  static void main(String args[]) throws InterruptedException{
       SynchronizedTest3 t = new SynchronizedTest3();

       Thread t1 = new Thread(t);
       Thread t2 = new Thread(t);
       t1.start();
       t2.start();

       t1.join();
       t2.join();

       System.out.println("线程全部结束");
    }

}
2) 对象锁-> 同步代码块锁
public class SynchronizeTest2 implements  Runnable {
    public  static SynchronizeTest2 test = new SynchronizeTest2();

    static int a = 0;
    @Override
    public void run() {
        synchronized (this){ // 代码块锁
            System.out.println("线程开始, 名称: " + Thread.currentThread().getName());
            for(int j=0;j<10000;j++){
                a ++;
            }
            System.out.println("线程结束, 名称: " + Thread.currentThread().getName());
        }
    }

    public static void main(String args[]) throws InterruptedException{
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
        System.out.println((t1.getState()));
        System.out.println((t2.getState()));
        System.out.println((t3.getState()));
        t1.join();
        t2.join();
        t3.join();
        System.out.println(a);
//        while ( t1.isAlive() || t2.isAlive() ){
//
//        }
        System.out.println("线程结束");
    }
}

3) 类锁-> 静态方法加锁
public class SynchronizedTest4 implements Runnable {
    // 类锁 -> 静态方法加锁

    static SynchronizedTest4 s1 = new SynchronizedTest4();
    static SynchronizedTest4 s2 = new SynchronizedTest4();


    @Override
    public void run() {
        method();
    }
    public synchronized static void method(){ // 必须是静态方法
        System.out.println("线程开始:"+ Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程结束:"+ Thread.currentThread().getName());
    }
    public static void main(String args[]) throws InterruptedException{

        Thread t1 = new Thread(s1);
        Thread t2 = new Thread(s2);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }


}

4) 类锁-> 类对象锁
package com.company;

public class SynchronizedTest5 implements Runnable{
    @Override
    public void run() {  // 类锁 -> class对象锁
        synchronized (SynchronizedTest5.class){
            System.out.println("线程开始:"+ Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程结束:"+ Thread.currentThread().getName());
        }

    }

    public static void main(String args[]) throws InterruptedException{
        SynchronizedTest5 s1 = new SynchronizedTest5();
        SynchronizedTest5 s2 = new SynchronizedTest5();

        Thread t1 = new Thread(s1);
        Thread t2 = new Thread(s2);

        t1.start();
        t2.start();

        while(t1.isAlive() || t2.isAlive()){

        }
        System.out.println("线程全部结束");
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值