博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
synchronized修饰普通方法,修饰静态方法,修饰代码块,修饰线程run方法 比较
阅读量:6653 次
发布时间:2019-06-25

本文共 4990 字,大约阅读时间需要 16 分钟。

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, 1Thread1 still alive, 2Thread1 still alive, 3Thread1 still alive, 1Thread1 still alive, 2Thread1 still alive, 3

  

 

转载地址:http://hmtto.baihongyu.com/

你可能感兴趣的文章
python小程序2
查看>>
Postfix(二):为邮件服务器配置收件服务器----dovecot
查看>>
浙江信访,从统一到智能的互联网转型之路
查看>>
关于淘宝应用毋须授权即可获取用户信息的问题
查看>>
算法问题:25匹马比赛,只有5条赛道,怎么样快速赛出速度最快的N匹马
查看>>
我的友情链接
查看>>
Win8/Win8.1常见错误代码的解决方法汇总
查看>>
SwipeListview拦截ViewPager滑动事件(改进)
查看>>
Python菜鸟之路: 封装通用excel操作
查看>>
[IOS笔记] - addChildViewController
查看>>
apache
查看>>
c语言:求一元二次方程的跟,系数a,b,c由键盘输入(要求考虑所有情况)
查看>>
c语言:用fgetc函数从键盘逐个输入字符,用fputc函数写到磁盘文件
查看>>
(技术分析)kvm虚拟化原理
查看>>
Linux 删除乱码文件
查看>>
Nginx反代Tomcat项目
查看>>
Windows10安装NTP服务器
查看>>
我的友情链接
查看>>
Docker 网络及数据卷设置 [三]
查看>>
一张图让你看懂JAVA线程间的状态转换
查看>>