0
点赞
收藏
分享

微信扫一扫

synchronized 关键字初解

暮晨夜雪 2022-04-13 阅读 19
java

synchronized 初解


前言

提示:这里可以添加本文要记录的大概内容:

题主 synchronized 关键字一直用的少,今天开贴记录下其用法和特性。


提示:以下是本篇文章正文内容,下面案例可供参考

一、synchronized 用来做什么?

示例:synchronized 关键字一直被用来做同步锁,其中加锁方式有许多,比如修饰代码块,修饰方法,其作用不尽相同,话不多说直接上示例

1. 对象锁

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadPool {

    private static ThreadPoolExecutor threadPoolExecutor;

    private static String a = "a";

    public ThreadPool() {

    }

    public void syncObjectLock() throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        synchronized (this) {
            System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
            currentThread.sleep(1000);
            System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        }
    }

    static class ThreadDemo implements Runnable {
        private ThreadPool threadPool;

        public ThreadDemo(ThreadPool threadPool) {
            this.threadPool = threadPool;
        }

        @Override
        public void run() {
            try {
                threadPool.syncObjectLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        ThreadPool threadPool = new ThreadPool();
        ThreadPool threadPool1 = new ThreadPool();
        Thread thread1 = new Thread(new ThreadDemo(threadPool), "t_1");
        Thread thread2 = new Thread(new ThreadDemo(threadPool), "t_2");
        Thread thread3 = new Thread(new ThreadDemo(threadPool), "t_3");
        Thread thread4 = new Thread(new ThreadDemo(threadPool), "t_4");
        Thread thread5 = new Thread(new ThreadDemo(threadPool1), "t_5"); 
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
    }
}

结果:可以看到 上文代码线程5 和线程 1 锁的是不同的对象,虽然对this 加锁,但是线程5 和 1 是同时进入同步代码块。可以看出对object 加锁在不同的实例上是锁不住的。
在这里插入图片描述

2.类锁

public void syncObjectLock() throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        synchronized (ThreadPool.class) { // 对 ThreadPool整个类上锁
            System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
            currentThread.sleep(1000);
            System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        }
    }

结果:可以看到 线程5 和其他线程都是排队进入的
在这里插入图片描述

3. 对整个方法上锁

代码如下(示例):

public synchronized void syncObjectLock() throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        currentThread.sleep(1000);
        System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
    }

结果:可以看到,线程5 和线程3 是同时进来的,方法上锁在不同的对象里边是不存在同步的
在这里插入图片描述

4. 锁静态变量

public void syncObjectLock() throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        synchronized (a) {
            System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
            currentThread.sleep(1000);
            System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        }
    }

结果:可以看到所有线程都是顺序执行的,所以静态变量上锁也是类级别的锁,不管多少实例都是锁住的
在这里插入图片描述

4. 锁静态方法

public synchronized static void syncObjectLock() throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        System.out.println("name: " + currentThread.getName() + " time: " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        System.out.println(currentThread.getName() + " -start:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        currentThread.sleep(1000);
        System.out.println(currentThread.getName() + " -end:" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
    }

结果:所有线程顺序进出,作用和锁住静态变量一样
在这里插入图片描述


总结

对对象和方法上锁,作用级别在同一个实例中才有效,对静态变量/静态方法上锁 为类级别的锁,在整个类级别生效,不管你是否同一个实例中。

举报

相关推荐

0 条评论