synchronized同步锁

在多线程的情况下,由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。
由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) {
//允许访问控制的代码
}
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。

public class TraditionalThreadSynchronized  {
     
    public static void main(String[] args) {
        new TraditionalThreadSynchronized().init();
    }
    void init(){
        final Outputer out  = new Outputer();
        //线程1
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    out.output1("Tmethod--->AAAAAA");
                }
            }
              
        }).start();
        //线程2
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    out.output3("Tmethod--->BBBBBB");
                }
            }
             
        }).start();
    } //end main
     
    static class Outputer{  //内部类
        /**
         * 方法内部加上线程锁,线程的锁只能锁同一个对象,如果有static方法那么线程锁必须为Class,不能为this
         */
        public void output1(String name){
            int len =name.length();
            synchronized (Outputer.class){ //synchronized参数可以为this,但是和static方法不能实现互斥,实现互斥只能为同一个对象
                for(int i=0;i<len;i++){
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
        /**
         * output2 和 output3不能实现同步,output2用的是对象锁的是this而output3是static方法要锁的话只能用class,如:output1
         * @param name
         */
        public synchronized void output2(String name){ //直接把锁加在方法上,默认把synchronized加载方法上那么他的互斥对象为this
            int len =name.length();
                for(int i=0;i<len;i++){
                    System.out.print(name.charAt(i));
                }
                System.out.println();
        }
        //static方法的线程锁
        public static synchronized void output3(String name){
            int len =name.length();
            for(int i=0;i<len;i++){
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
    }
}

转载于:https://www.cnblogs.com/dyc-cfc/p/4256304.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ socket学习(1.3)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 在这里c socket学习&#xff08;1.1&#xff09;学到了怎么样建立TCP&#xff0c;然后通过TCP连接发送、接收信息。 但是都是一次性的&#xff0c;当时是接收信息后就结束…

一个一线城市的IT白领的生活成本:3万/年

自从大学毕业&#xff0c;经济独立&#xff0c;就开始全面统计各种生活开支。仔细的去统计下&#xff0c;发现开销还是挺大的。 定理&#xff1a;开销越大&#xff0c;就意味着你每个月的收入必须越高。 三族鼎立节余族: 收入-开支 > 0月光族&#xff1a;收入-开支 0透支族…

android 编译共享ccache的缓存

1. android自带的ccache版本号(2.4版本号)过低&#xff0c;是无法支持以上的功能的&#xff0c;须要使用新版ccache。2. 最新的ccache请到http://ccache.samba.org/download.html下载3. 下载解压之后&#xff0c;在linux底下进入ccache文件夹&#xff0c;执行:./configure./mak…

一位软件工程师的6年总结

作者&#xff1a;成晓旭 “又是一年毕业时”&#xff0c;看到一批批学子离开人生的象牙塔&#xff0c;走上各自的工作岗位&#xff1b;想想自己也曾经意气风发、踌躇满志&#xff0c;不觉感叹万千……本文是自己工作6年的经 历沉淀或者经验提炼&#xff0c;希望对所有的软件工…

c++ socket学习(1.4)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 前面学到了TCP怎么循环发包&#xff0c;但是TCP连接的话会出现一个问题粘包。 TCP连接接收到的数据并不是马上读取到内存里面的&#xff0c;而是放在缓冲区&#xff0c;让…

mongodb中分页显示数据集的学习

mongodb中分页显示数据集的学习 这次继续看mongodb中的分页。首先依然是插入数据&#xff1a; 1&#xff09; db.Blog.insert( { name : "Denis", age : 20, city : "Princeton" } ) db.Blog.insert( { name : "Abe", age : 30, city : &quo…

学习编程,英语很重要!!

学会编程&#xff0c;可能不需要英语多好&#xff0c;但是学号编程&#xff0c;英语真的很重要&#xff01;&#xff01;&#xff01; 好多文档&#xff0c;demo全是英文的&#xff0c;蛋疼&#xff0c;应许需要学习&#xff01;&#xff01;&#xff01;转载于:https://www.cn…

c++ socket学习(1.5)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 这次来试一下使用TCP来传输文件&#xff0c;其实传输数据和差不多&#xff0c;就是多一个读取文件&#xff0c;和一个写文件而已。 服务端 int readlan 100; std::ifst…

matlab生成HEX文件-任意信号 大于64K长度

HEX文件格式不赘述&#xff0c;写里直接放上代码。请批评改正。 1 %%convert a signal data into hex file format2 % data format:16bit 3 % signal length: less than 2^24-14 % author: Yang Li yangli0534gmail.com5 % data:2015.01.276 7 clear all;8 close all;9 clc; 10…

移动端网页中ViewPort的使用

<meta name"viewport" content"widthdevice-width,target-densitydpihigh-dpi, initial-scale1.0, minimum-scale1.0, maximum-scale1.0, user-scalableno"> <meta name”viewport” content”widthdevice-width, initial-scale1.0, user-scalabl…

c++ socket学习(1.6)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 这次来看看UDP 之前在c socket学习&#xff08;1.2&#xff09;讲过UDP怎么发送了&#xff0c;那现在来做一个可以一直发送的。 这次没有什么接收端和发送端了&#xff0…

redis学习笔记——(1)

1. NoSQL&Redis介绍 NoSQL&#xff0c;Not Only SQL&#xff0c;是非关系型的数据库。传统的关系数据库不能满足超大规模和高并发的应用。 是以Key-Value的形式存储&#xff0c;&#xff08;例如JSON,XML&#xff09;&#xff0c;不一定遵循传统数据库的一些基本要求&#…

命令模式坚决svn树冲突(local unversioned, incoming add upon update)

当工作目录修改删除过时更新使用svn更新就容易发生树冲突“Tree Confilict”.会出现类似提示。 local unversioned, incoming add upon update1local unversioned,incoming add upon update如果使用图形化客户端可以通过对比文件和解决冲突按钮进行解决&#xff0c; 如果是使用…

c++ vector学习

参考资料&#xff1a; cppreference.com 本文代码&#xff1a; 本文源码 目录隐式成员函数1.operator &#xff08;赋值给容器&#xff09;2.assign &#xff08;将值赋给容器&#xff09;元素访问3.at &#xff08;访问指定元素&#xff0c;进行下标检查&#xff09;4.operat…

linux关闭声音

对于CentOS/Redhat/RHEL/Fedora系统&#xff0c;使用root身份执行&#xff1a;echo "alias pcspkr off" >> /etc/modprobe.conf转载于:https://www.cnblogs.com/keethebest/p/3434821.html

Bundle Identifier

Bundle Identifier : 产品的唯一标识符 1.在模拟器上面&#xff0c;只能有一个唯一的标识符的应用程序 2.在AppStore上&#xff0c;所有的应用程序的Bundler ID都是唯一的 Bundle ID 公司的反向域名 产品名 Bundle ID 不支持中文&#xff0c;因此如果是上架产品&#xff0c;需…

c++ array学习

参考资料&#xff1a; cppreference.com 本文代码&#xff1a; 本文源码 array和vector的区别是array是和C中的数组类似&#xff0c;不能动态改变数组大小&#xff0c;所以会比vector少很多函数。 目录隐式定义的成员函数1.operator &#xff08;将另一个容器拷贝过来&#x…

lucene4入门(2)搜索

欢迎转载http://www.cnblogs.com/shizhongtao/p/3440479.html 接着上一篇&#xff0c;这里继续搜索&#xff0c;对于搜索和创建一样&#xff0c;首先你要确定搜索位置&#xff0c;然后用规定的类来读取。还要注意一点&#xff0c;确定分词器&#xff0c;因为不同的分词器所创建…

Topcoder SRM 648 (div.2)

第一次做TC全部通过&#xff0c;截图纪念一下。 终于蓝了一次&#xff0c;也是TC上第一次变成蓝名&#xff0c;下次就要做Div.1了&#xff0c;希望div1不要挂零。。。_(:зゝ∠)_ A. KitayutaMart2 万年不变的水题。 #include<cstdio> #include<cstring> #include&…

Kadane's algorithm学习

Kadane’s algorithm 简单来说就是用来计算数组中的连续子数组之和最大是多少 vector<int> vec; int temp 0,ans 0; for(int i0;i<vec.size();i){temp max(tempvec[i],vec[i]);ans max(temp,ans); } return ans;循环的第一行就是用来比较当前位置的值和前面数组…