Java 线程 synchronized 学习

  **synchronized** 关键字:当一个方法被synchronized关键字修饰的时候,该方法叫同步方法

  Java中的每个对象都有一个锁(lock)或者叫监视器(monitor),当访问某个线程的访问synchronized 方法时,表示给该对象上锁,此时其他任何线程都无法访问该synchronized 方法,直到之前的那个线程执行完方法或者抛出异常,那个该对象的锁被释放掉,其他线程才可以访问该synchronized 方法


public class ThreadTest {

    public static void main(String[] args) {

        Example example = new Example();

        TheThread t1 = new TheThread(example);

        TheThread2 t2 = new TheThread2(example);

        t1.start();

        t2.start();

    }

}

class Example {

    public synchronized void execute() {

        for (int i = 0; i < 10; i++) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("hello: " + i + " ");
        }
    }

    public synchronized void execute2() {

        for (int i = 0; i < 10; i++) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("word: " + i + " ");
        }
    }

}

class TheThread extends Thread {

    private Example example;

    public TheThread(Example example) {

        this.example = example;
    }

    @Override
    public void run() {
        super.run();

        example.execute();
    }
}

class TheThread2 extends Thread {

    private Example example;

    public TheThread2(Example example) {

        this.example = example;
    }

    @Override
    public void run() {
        super.run();
        example.execute2();
    }
}

打印的顺序是

hello: 0 
hello: 1 
hello: 2 
hello: 3 
hello: 4 
hello: 5 
hello: 6 
hello: 7 
hello: 8 
hello: 9 
word: 0 
word: 1 
word: 2 
word: 3 
word: 4 
word: 5 
word: 6 
word: 7 
word: 8 
word: 9 

从结果上看是有序的,也就是说如果一个对象有多个synchronized方法,某一个时刻某个线程已经进入某个synchronized 方法,那么该方法没有执行完之前,其他线程无法访问该对象的任何synchronized 方法,当然非synchronized 还是可以访问的。


  将execute2方法改成staticpublic synchronized static void execute2()
  打印的结果如下:
   word: 0 
   hello: 0 
   hello: 1 
   word: 1 
   word: 2 
   hello: 2 
   word: 3 
   hello: 3 
   hello: 4 
   word: 4 
   hello: 5 
   word: 5 
   hello: 6 
   word: 6 

 原因分析:static修饰的方法或者变量不属于任何对象,属于类的,当synchronized 修饰一  个static方法时,锁的不是当前对象,而是当前对象所对应的class对象,而一个类不管有多少对象,其所对应的class对象只有一个。这个时候把execute方法也改成static,打印结果如下:
  hello: 0 
  hello: 1 
  hello: 2 
  hello: 3 
  hello: 4 
  hello: 5 
  hello: 6 
  hello: 7 
  hello: 8 
  hello: 9 
  word: 0 
  word: 1 
  word: 2 
  word: 3 
  word: 4 
  word: 5 
  word: 6 
  word: 7 
  word: 8 
  word: 9 

再次验证,如果某个synchronized 方法是static的,当线程访问该方法时,它锁的并不是synchronized 方法所处在的对象,而是这个类的Class对象,而Java一个类的对象无论有多少个,Class对象始终只有一个,因此当多个线程访问同一个类多个对象的不同synchronized static方法时,执行的结果也是按照顺序的,也就是一个线程执行完毕后另外一个线程才能执行。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值