java-测试synchronized使用xxx.class和this使用的区别

synchronized测试1

写两个线程调用同一个方法,在其中分别做一个class和this的调用,看结果

1.xx.class

public class Test{
    public static void main(String[] args) {
        System.out.println(new Date().toLocaleString()+";开始创建t1...");
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                new Test().test("t1");
            }
        });
        System.out.println(new Date().toLocaleString()+";开始执行t1...");
        t1.start();
        System.out.println(new Date().toLocaleString()+";开始创建t2...");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                new Test().test("t2");
            }
        });
        System.out.println(new Date().toLocaleString()+";开始执行t2...");
        t2.start();
    }

    public  void test(String n){
        System.out.println(new Date().toLocaleString()+";"+n+"来了");
        synchronized (Test.class) {
            System.out.println(new Date().toLocaleString()+";"+n+"   我在这里休眠5秒");
            try {
                Thread.sleep(5*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(new Date().toLocaleString()+";"+n+"   结束");
    }
}

打印

2015-10-19 13:56:46;开始创建t1...
2015-10-19 13:56:47;开始执行t1...
2015-10-19 13:56:47;开始创建t2...
2015-10-19 13:56:47;t1来了
2015-10-19 13:56:47;t1   我在这里休眠5秒
2015-10-19 13:56:47;开始执行t2...
2015-10-19 13:56:47;t2来了
2015-10-19 13:56:52;t2   我在这里休眠5秒
2015-10-19 13:56:52;t1   结束
2015-10-19 13:56:57;t2   结束

从打印的结果可以看出,使用class在执行到synchronized时会等待其他占用的线程执行玩才会继续执行

2.对比this

//将上面的案例中的synchronized (Test.class) { 修改成
synchronized (this) {

执行打印输出结果

2015-10-19 14:01:22;开始创建t1...
2015-10-19 14:01:22;开始执行t1...
2015-10-19 14:01:22;开始创建t2...
2015-10-19 14:01:22;t1来了
2015-10-19 14:01:22;开始执行t2...
2015-10-19 14:01:22;t1   我在这里休眠5秒
2015-10-19 14:01:22;t2来了
2015-10-19 14:01:22;t2   我在这里休眠5秒
2015-10-19 14:01:27;t1   结束
2015-10-19 14:01:27;t2   结束

可以看到,使用this执行线程时只会考虑到同一个线程中的同步问题,严格来说是无法达到真正意义上的线程同步

通过调用不同的方法再次测试

首先看使用class代码展示

    public class Test{
        public static void main(String[] args) {
            System.out.println(new Date().toLocaleString()+";开始创建t1...");
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    new Test().test("t1");
                }
            });
            System.out.println(new Date().toLocaleString()+";开始执行t1...");
            t1.start();
            System.out.println(new Date().toLocaleString()+";开始创建t2...");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    new Test().test1("t2");
                }
            });
            System.out.println(new Date().toLocaleString()+";开始执行t2...");
            t2.start();
        }

        public  void test(String n){
            System.out.println(new Date().toLocaleString()+";"+n+"来了");
            synchronized (Test.class) {
                System.out.println(new Date().toLocaleString()+";"+n+"   我在这里休眠5秒");
                try {
                    Thread.sleep(5*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(new Date().toLocaleString()+";"+n+"   结束");
        }

        public  void test1(String n){
            System.out.println(new Date().toLocaleString()+";"+n+"来了");
            synchronized (Test.class) {
                System.out.println(new Date().toLocaleString()+";"+n+"   我在这里休眠5秒");
                try {
                    Thread.sleep(5*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(new Date().toLocaleString()+";"+n+"   结束");
        }
    }

执行打印结果

2015-10-19 14:04:58;开始创建t1...
2015-10-19 14:04:58;开始执行t1...
2015-10-19 14:04:58;开始创建t2...
2015-10-19 14:04:58;t1来了
2015-10-19 14:04:58;t1   我在这里休眠5秒
2015-10-19 14:04:58;开始执行t2...
2015-10-19 14:04:58;t2来了
2015-10-19 14:05:03;t2   我在这里休眠5秒
2015-10-19 14:05:03;t1   结束
2015-10-19 14:05:08;t2   结束

通过打印结果可以看到基本与同一个方法执行的结果相同

同样也做this的测试

//将上面的案例中的synchronized (Test.class) { 修改成
synchronized (this) {

打印结果

2015-10-19 14:08:22;开始创建t1...
2015-10-19 14:08:22;开始执行t1...
2015-10-19 14:08:22;开始创建t2...
2015-10-19 14:08:22;t1来了
2015-10-19 14:08:22;t1   我在这里休眠5秒
2015-10-19 14:08:22;开始执行t2...
2015-10-19 14:08:22;t2来了
2015-10-19 14:08:22;t2   我在这里休眠5秒
2015-10-19 14:08:27;t1   结束
2015-10-19 14:08:27;t2   结束

打印结果基本相同

所以得出:在使用线程同步时,处理特殊情况外基本应该使用class

测试static中的线程同步

    public class Test{
        public static void main(String[] args) {
            System.out.println(new Date().toLocaleString()+";开始创建t1...");
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    test("t1");
                }
            });
            System.out.println(new Date().toLocaleString()+";开始执行t1...");
            t1.start();
            System.out.println(new Date().toLocaleString()+";开始创建t2...");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    test("t2");
                }
            });
            System.out.println(new Date().toLocaleString()+";开始执行t2...");
            t2.start();
        }

        public static void test(String n){
            System.out.println(new Date().toLocaleString()+";"+n+"来了");
            synchronized (Test.class) {
                System.out.println(new Date().toLocaleString()+";"+n+"   我在这里休眠5秒");
                try {
                    Thread.sleep(5*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(new Date().toLocaleString()+";"+n+"   结束");
        }

    }

打印

2015-10-19 14:10:22;开始创建t1...
2015-10-19 14:10:23;开始执行t1...
2015-10-19 14:10:23;开始创建t2...
2015-10-19 14:10:23;t1来了
2015-10-19 14:10:23;t1   我在这里休眠5秒
2015-10-19 14:10:23;开始执行t2...
2015-10-19 14:10:23;t2来了
2015-10-19 14:10:28;t2   我在这里休眠5秒
2015-10-19 14:10:28;t1   结束
2015-10-19 14:10:33;t2   结束

从结果中可以看出与class执行是一样的,不区分static。

时间: 2024-10-16 16:22:58

java-测试synchronized使用xxx.class和this使用的区别的相关文章

Java的synchronized的同步代码块和同步方法的区别

线程同步问题大都使用synchronized解决,有同步代码块和同步方法的两种方式,主要记一下这两种的区别 测试代码: 1 package com.xujingyang.testThread; 2 3 public class SynObj{ 4 public synchronized void showA(){ 5 System.out.println("showA.."); 6 try { 7 Thread.sleep(3000); 8 } catch (InterruptedEx

java.lang.UnsatisfiedLinkError: no XXX in java.library.path

其中涉及的测试源码如下: For those who didn't install Javawith default settings, a systematic way for solving JNI class path problem is:1> include "System.out.println(System.getProperty("Java.library.path")); " in your "static" block,

JAVA多线程synchronized详解

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块. 尤其关键

Java关键字synchronized详解

Java关键字synchronized详解 博客分类: Java综合 Java多线程thread互联网制造 synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行 它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法: 通过在方法声明中

java:synchronized 同步代码块

synchronized:利用上锁实现数据同步,避免多线程操作的情况下,数据出现异常. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行. 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 在代码块前加上 synchronized关键字,则此代码块就成为同步代码块, 格式: synchronized(同步对象){ 需要同步的代码: } class MyThread implements Runnab

java测试网络连接是否成功并设置超时时间

/** * 获取RMI接口状态 * * @return "0":服务正常,"1": 连接报错,"2":连接超时 */ @Override public String getRMIJkzt() { final ExecutorService es = Executors.newFixedThreadPool(1); Callable<String> callable = new Callable<String>() {//使

Java测试工具使用(1)--Junit

在进行测试之前需要导入junit的两个包,分别是 junit:4.12;hamcrest-core:1.1 1.基本测试标签 @Test.@Before.@After 2.组测试 有时候多个测试文件,如果一个一个去执行肯定浪费时间,那么如何做呢? 假如现在有FirTest.java,SecTest.java,每个测试类中有多个方法,想把这个文件一起测试应该如何做呢? 新建一个java测试文件,命名为GroupTest,然后编写代码 @RunWith(Suite.class) @Suite.Sui

JAVA测试编程知识点

JAVA测试编程会涉及的知识点: 1.      testNg框架 2.      http协议和HttpClient. 在依据http头进行不同数据解析: Transfer-Encoding:chunked 在chunked 为ture时接口分段传数据怎么解析处理 chunked 不为ture时接口测试已可以处理. Content-Encoding: gzip 接口数据压缩的怎么解析处理 结合Transfer-Encoding:chunked为ture时接口数据怎么解析处理 不同Content

Java基础-synchronized关键字的用法(转载)

原文地址:http://blog.csdn.net/cq361106306/article/details/38736551 synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰?this或者非静态方法或者是一个实例的时候,所同步的锁是加在this或者实例对象引用上面的.比如a,b同为Main类的实例化对象,a调用被同步的方法,和b调用被同步的方法,没有形成互斥.但是不同线程的a对象调用被同步的方法就被互斥了.