zoukankan      html  css  js  c++  java
  • synchronized修饰普通方法,修饰静态方法,修饰代码块,修饰线程run方法 比较

    synchronized用于多线程设计,有了synchronized关键字,多线程程序的运行结果将变得可以控制。synchronized关键字用于保护共享数据。

    synchronized实现同步的机制:synchronized依靠"锁"机制进行多线程同步,"锁"有2种,一种是对象锁,一种是类锁

    1.依靠对象锁锁定

    初始化一个对象时,自动有一个对象锁。synchronized {普通方法}依靠对象锁工作,多线程访问synchronized方法,一旦某个进程抢得锁之后,其他的进程只有排队对待。


    synchronized {普通方法}依靠对象锁工作,多线程访问synchronized方法,一旦某个进程抢得锁之后,其他的进程只有排队对待。
     
    synchronized void method{}功能上,等效于
    void method{
       synchronized(this) {
        ...
       }
    }
    通过代码看比较清楚:
    public class TestSynchronized {
        public synchronized void method1() throws InterruptedException {
            System.out.println("method1 begin at:" + System.currentTimeMillis());
            Thread.sleep(6000);
            System.out.println("method1 end at:" + System.currentTimeMillis());
        }
        public synchronized void method2() throws InterruptedException {
            while(true) {
                System.out.println("method2 running");
                Thread.sleep(200);
            }
        }
        static TestSychronized instance = new TestSychronized();
        public static void main(String[] args) {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        instance.method1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    for(int i=1; i<4; i++) {
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("Thread1 still alive");
                    }                    
                }
            });
            
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        instance.method2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            
            thread1.start();
            thread2.start();    
            
        }
    }
    

     运行结果:thread2一直等到thread1中的method1执行完了之后才执行method2,说明method1和method2互斥

    synchronized {修饰代码块}的作用不仅于此,synchronized void method{}整个函数加上synchronized块,效率并不好。在函数内部,可能我们需要同步的只是小部分共享数据,其他数据,可以自由访问,这时候我们可以用 synchronized(表达式){//语句}更加精确的控制
    • 2.synchronized {static方法}此代码块等效于
    void method{
       synchronized(Obl.class)
       }
    }
    使用该类的类对象的锁定去做线程的共享互斥.
    package com.free4lab.lol;
    
    public class TestSychronized {
        public synchronized static void method1() throws InterruptedException {
            System.out.println("method1 begin at:" + System.currentTimeMillis());
            Thread.sleep(6000);
            System.out.println("method1 end at:" + System.currentTimeMillis());
        }
        public synchronized static void method2() throws InterruptedException {
            while(true) {
                System.out.println("method2 running");
                Thread.sleep(200);
            }
        }
        static TestSychronized instance1 = new TestSychronized();
        static TestSychronized instance2 = new TestSychronized();
        public static void main(String[] args) {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        instance1.method1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    for(int i=1; i<4; i++) {
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("Thread1 still alive");
                    }                    
                }
            });
            
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        instance2.method2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            
            thread1.start();
            thread2.start();    
            
        }
    }
    

    输出效果也是method1和method2互斥

     
    • 3.synchronized {run方法}run方法的锁定.
    这个举例比较好说
    package com.free4lab.lol;
    
    public class TestSychronized {
        static TestSychronized instance = new TestSychronized();
        public static void main(String[] args) {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                    public synchronized void run() {
                        
                        for(int i=1; i<4; i++) {
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("Thread1 still alive, " + i);
                        }                    
                    }
            });
            new Thread(thread1).start();
            new Thread(thread1).start();
        }
    }
    

    如果加了synchronized当前线程取完所有数据后,才会释放锁,输出结果是有序的

    Thread1 still alive, 1
    Thread1 still alive, 2
    Thread1 still alive, 3
    Thread1 still alive, 1
    Thread1 still alive, 2
    Thread1 still alive, 3
    

      

     

  • 相关阅读:
    String和StringBuffer、StringBuilder的区别
    猜字谜小游戏编程
    const 和非 const 函数重载
    沉溺于 Mac,沉溺于 XCode
    开源软件与自由软件的区别——个人体会
    C++/C宏定义中## 连接符与# 符的含义
    const 关键字用法代码观
    博客搬家
    注销、关闭和重启计算机
    c/c++笔试题——const类型的成员函数内部如何改变成员变量
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/7684825.html
Copyright © 2011-2022 走看看