学习Java,synchronized关键字的使用

2024-01-24

所以我正在测试synchronized关键词。这是我尝试过的一个例子:

public class MyTest {
    static int i = 0;
    public static void main(String[] args) {
        new Thread(t1).start();
        new Thread(t2).start();
    }

    private static void countMe(String name){
        i++;
        System.out.println("Current Counter is: " + i + ", updated by: " + name);
    }

    private static Runnable t1 = new Runnable() {
        public void run() {
            try{
                for(int i=0; i<5; i++){
                    countMe("t1");
                }
            } catch (Exception e){}

        }
    };

    private static Runnable t2 = new Runnable() {
        public void run() {
            try{
                for(int i=0; i<5; i++){
                    countMe("t2");
                }
            } catch (Exception e){}
       }
    };
}  

当我运行它时,调用的输出countMe()两个线程的方法生成以下输出:

Current Counter is: 1
Current Counter is: 2
Current Counter is: 4
Current Counter is: 5
Current Counter is: 6
Current Counter is: 7
Current Counter is: 3
Current Counter is: 8
Current Counter is: 9
Current Counter is: 10  

当我改变方法时countMe() to:

private synchronized static void countMe(){
        i++;
        System.out.println("Current Counter is: " + i);
}  

我得到这个输出:

Current Counter is: 1
Current Counter is: 2
Current Counter is: 3
Current Counter is: 4
Current Counter is: 5
Current Counter is: 6
Current Counter is: 7
Current Counter is: 8
Current Counter is: 9
Current Counter is: 10  

虽然这让我清楚地了解了synchronized,我想知道是否还有其他原因,我们可以使用synchronized。或者我在这里所做的,是我们需要使用这个的唯一原因synchronized关键词?

谢谢。

EDIT:另一件令我困惑的事情是,在第一个输出中,为什么计数器在 7 之后变为 3。这对我来说似乎有点不可能,但每次我尝试时都会出现类似的结果,这是正常的吗?


两件事情:

首先,同一对象上的同步方法的两次调用不可能交错。当一个线程正在执行对象的同步方法时,调用同一对象的同步方法的所有其他线程都会阻塞(挂起执行),直到第一个线程完成该对象。

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立发生之前关系。这保证了对象状态的更改对所有线程都是可见的。

同步方法启用了一种防止线程干扰和内存一致性错误的简单策略:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都通过同步方法完成。 (一个重要的例外:final 字段在构造对象后无法修改,一旦构造对象就可以通过非同步方法安全地读取)。

source: http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习Java,synchronized关键字的使用 的相关文章

随机推荐

  • 从 MySQL 中的分层数据生成基于深度的树(无 CTE)

    嗨 很多天我一直在 MySQL 中解决这个问题 但是我无法弄清楚 你们有什么建议吗 基本上 我有一个类别表 其中包含以下域 id name 类别名称 以及parent 类别的父类别的 ID 示例数据 1 Fruit 0 2 Apple 1
  • GAE python:如何使用delete_serving_url

    首先我将图像存储 import cloudstorage as gcs path bucket folder image jpg with gcs open path w as f f write data 然后我得到服务网址 url im
  • 如何动态调整导航栏中的标题大小

    我有一些视图显示在导航控制器中 其中两个视图的导航栏标题较长 问题是 当标题太长而无法容纳时 某些字符会被截断并添加 有什么方法可以告诉导航栏自动调整标题文本的大小以适应 在 ViewDidload 中使用以下代码 目标C self tit
  • 如何使用 2.01 的功能,同时仍然通过一个 apk 支持 1.5?

    我希望我的 Activity 使用 2 01 的某些功能 但我需要它能够在 1 5 设备上运行 据我所知 1 5 设备将无法运行 2 01 功能 但这很好 但我仍然希望他们能够使用其余的活动 我使用 Eclipse 作为 IDE 如何正确设
  • mysql中如何选择一段时间?

    我想做一段时间的MySql选择 但我不知道如何正确地制作它 这就是我尝试过的 SELECT FROM rapoarte WHERE DATE ziua BETWEEN 2010 01 12 AND 2011 01 14 你能帮忙吗 谢谢 塞
  • 数据声明的类型类约束

    显然 在数据声明上放置类型类约束是一个坏主意 src https stackoverflow com questions 2354707 in haskell is there num a infinity a rq 1 comment23
  • 如何编写爬虫?

    我曾想过尝试编写一个简单的爬虫程序 它可以爬行并为我们的 NPO 网站和内容生成其发现结果列表 有人对如何做到这一点有任何想法吗 您将爬虫指向何处开始 它如何发回其发现并仍然继续爬行 它如何知道它发现了什么等等 可以肯定的是 你将重新发明轮
  • 透明操作栏下方的导航抽屉

    我通过使用 GunnarKarlsson 在此处显示的以下代码获得透明的操作栏 透明操作栏 自定义选项卡颜色 https stackoverflow com questions 13726214 transparent actionbar
  • Spring Oauth2 中的 CORS 错误

    我正在使用 Spring 安全性和 Oauth2 但是我是Spring Oauth2的新手 当前端访问资源时 我遇到了CORS错误 我使用以下过滤器来允许其他域访问该资源 Component Order Integer MAX VALUE
  • 如何在类型已实现 Display 的特征对象上实现 Display

    我有一些代码返回类型的特征对象MyTrait这样它就可以返回几个不同的结构之一 我想实施Display特征对象的特征 以便我可以打印该对象 并将详细信息委托给各种结构 因为它们每个都需要自己的自定义格式化程序 我可以通过将格式化方法作为其中
  • 如何通过 JavaFX 显示来自 MYSQL 的阿拉伯语查询搜索?

    SELECT FROM employee WHERE name LIKE 上面的查询工作正常 并通过 phpmyAdmin 查询找到该元素 但在 JavaFX 中使用它却找不到它 并进行英语搜索 那么我需要在java中添加什么才能允许我用阿
  • 哪些语言支持*递归*函数文字/匿名函数?

    看来主流语言都支持函数字面量 http en wikipedia org wiki First class function这些日子 他们也被称为匿名函数 http en wikipedia org wiki Anonymous funct
  • 使用 C# 聚合 $lookup

    我有以下 MongoDb 查询正在运行 db Entity aggregate match Id 12345 lookup from OtherCollection localField otherCollectionId foreignF
  • 如何检查视差是否启用

    我正在制作一个壁纸应用程序 想检查用户是否在他的 iOS 7 设备上启用了视差 Objective C 有没有办法可以检查这一点 Apple 是否授予我们开发人员检查此布尔值的权限 即 如果启用视差 则执行步骤 1 否则执行步骤 2 从 i
  • 无法通过 httr::user_agent 设置用户代理

    尝试通过以下方式更改用户代理时 我需要考虑什么特别的事情吗 httr user agent in a httr GET 在 MS Windows 上调用 我在用着R 3 1 0 and httr 0 3 按照以下示例 user agent
  • 使用带有特殊字符的 URL 名称是个好主意吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 URL 页面名称 中包含非英文字符 如 URL 中的中文名称 是否有利于 SEO 从搜索引擎优化的角度来看 一般网址规则 网络属性上的所有 UR
  • 子进程接收父进程的SIGINT

    我有一个使用 Qt Framework 的简单程序 它使用QProcess来执行RAR并压缩一些文件 在我的程序中我正在捕捉SIGINT并在发生时在我的代码中执行某些操作 signal SIGINT unix handler When SI
  • 如何禁用 PrimeFaces FileUpload 中的“选择”按钮直至上传完成

    是否可以阻止 禁用 FileUpload 中的 选择 按钮 我在高级模式下使用 p fileUpload 并设置 multiple true 如果我单击 上传 按钮开始上传所有文件 我想阻止添加更多文件 直到所有文件上传完毕 PrimeFa
  • 如何使用 C# 中的 MySQL 存储过程将表作为存储过程的输入发送?我有 T-SQL 工作

    在 Transact SQL 中 我有存储过程的输入参数 DataTable InputTabel READONLY InputTabel 定义为 CREATE TYPE InputTabel AS TABLE ID INT NULL RE
  • 学习Java,synchronized关键字的使用

    所以我正在测试synchronized关键词 这是我尝试过的一个例子 public class MyTest static int i 0 public static void main String args new Thread t1