A-A+

Java-Synchronized用法(3)

2019年01月06日 技术, 默认 暂无评论 阅读 1,362 次

Synchronized主要有以下几种用法:

1. 加在方法上:这里包括加在实例方法上、加在静态方法上。

2. 方法块:这里包括锁定this、锁定Class、锁定实例对象、锁定静态对象。

今天主要通过例子演示一下第二个用法:锁定实例对象和锁定静态对象。

首先是锁定实例对象

测试代码如下:

package com.xnck.example.sbtest;

import org.junit.Test;

import java.util.Scanner;

public class ThreadTest {

    private final byte[] lockThis = new byte[0];

    public void printThisLock(String input) {
        synchronized (lockThis) {
            System.out.println(input + System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("3秒后的" + input + System.currentTimeMillis());
        }
    }

    private void waitToQuite() {
        new Scanner(System.in).next();
    }

    //region 测试方法

    /**
     * 锁定实例对象,相同对象调用等待
     */

    @Test
    public void test4() {

        final ThreadTest test = new ThreadTest();

        new Thread(() -> {
            System.out.println("第一个线程已启动" + System.currentTimeMillis());
            test.printThisLock("我是第一个线程");
        }).start();

        new Thread(() -> {
            System.out.println("第二个线程已启动" + System.currentTimeMillis());
            test.printThisLock("我是第二个线程");
        }).start();

        waitToQuite();
    }

    /**
     * 锁定实例对象,不同对象调用不需要等待
     */

    @Test
    public void test5() {

        final ThreadTest test1 = new ThreadTest();
        final ThreadTest test2 = new ThreadTest();

        new Thread(() -> {
            System.out.println("第一个线程已启动" + System.currentTimeMillis());
            test1.printThisLock("我是第一个线程");
        }).start();

        new Thread(() -> {
            System.out.println("第二个线程已启动" + System.currentTimeMillis());
            test2.printThisLock("我是第二个线程");
        }).start();

        waitToQuite();
    }

    //endregion
}

测试结果如下:


锁定实例对象,同一个对象,被调用时等待

锁定实例对象,不同对象,调用时不需要等待

然后是锁定静态对象

测试代码如下:

package com.xnck.example.sbtest;

import org.junit.Test;

import java.util.Scanner;

public class ThreadTest {

    private final static byte[] lockStatic = new byte[0];

    public void printStaticLock(String input) {
        synchronized (lockStatic) {
            System.out.println(input + System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("3秒后的" + input + System.currentTimeMillis());
        }
    }

    private void waitToQuite() {
        new Scanner(System.in).next();
    }

    //region 测试方法

    /**
     * 锁定静态对象,相同对象调用等待
     */

    @Test
    public void test4() {

        final ThreadTest test = new ThreadTest();

        new Thread(() -> {
            System.out.println("第一个线程已启动" + System.currentTimeMillis());
            test.printStaticLock("我是第一个线程");
        }).start();

        new Thread(() -> {
            System.out.println("第二个线程已启动" + System.currentTimeMillis());
            test.printStaticLock("我是第二个线程");
        }).start();

        waitToQuite();
    }

    /**
     * 锁定静态对象,不同对象调用等待
     */

    @Test
    public void test5() {

        final ThreadTest test1 = new ThreadTest();
        final ThreadTest test2 = new ThreadTest();

        new Thread(() -> {
            System.out.println("第一个线程已启动" + System.currentTimeMillis());
            test1.printStaticLock("我是第一个线程");
        }).start();

        new Thread(() -> {
            System.out.println("第二个线程已启动" + System.currentTimeMillis());
            test2.printStaticLock("我是第二个线程");
        }).start();

        waitToQuite();
    }

    //endregion
}

测试结果如下:


锁定静态对象,相同对象调用需要等待

锁定静态对象,不同对象调用需要等待
觉的不错?可以关注我的公众号↑↑↑

给我留言

Copyright © 字痕随行 保留所有权利.   Theme  Ality

用户登录

分享到: