当前位置: 首页 > 面试题库 >

学习Java,使用同步关键字

方嘉志
2023-03-14
问题内容

所以我正在用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()为:

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关键字的唯一原因?

谢谢。

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


问题答案:

两件事情:

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

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

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

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



 类似资料:
  • 本文向大家介绍Java中的同步关键字,包括了Java中的同步关键字的使用技巧和注意事项,需要的朋友参考一下 当我们在程序中启动两个或多个线程时,可能会出现多个线程尝试访问同一资源,最终由于并发问题,它们可能产生无法预料的结果的情况。例如,如果多个线程试图在同一文件中写入数据,则它们可能会破坏数据,因为其中一个线程可以覆盖数据,或者一个线程同时打开同一文件时,另一个线程可能正在关闭同一文件。 因此,

  • 问题内容: c#是否具有自己的java“ synchronized”关键字版本? 即在Java中,可以将其指定为函数,对象或代码块,如下所示: 要么 问题答案: 首先-大多数类将永远不需要是线程安全的。使用YAGNI:仅当你知道实际上将要使用它(并对其进行测试)时,才应用线程安全性。 对于方法级的东西,有: 这也可以用于访问器(属性和事件): 请注意,默认情况下,类似字段的事件是同步的,而自动实现

  • 本文向大家介绍java同步与异步的学习笔记整理,包括了java同步与异步的学习笔记整理的使用技巧和注意事项,需要的朋友参考一下 概念: 1、同步:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。 2、异步:将用户请求放入消息队

  • 这个问题以前可能已经回答过了,但是由于这个问题的复杂性,我需要一个确认。所以我重新措辞这个问题 问题1:当一个线程进入一个同步块时,内存屏障将包括被触摸的任何字段,而不仅仅是我同步的对象的字段?因此,如果在一个同步块中修改了许多对象,那么在线程内存缓存之间会有大量内存移动。 问题 2 : 在线程 1 中隐式地是“发生前”关系的一部分? 我希望是这样,但可能不是这样。如果没有,有没有一个技巧可以让它

  • 本文向大家介绍Java中使用synchronized关键字实现简单同步操作示例,包括了Java中使用synchronized关键字实现简单同步操作示例的使用技巧和注意事项,需要的朋友参考一下 简单记录下java中synchronized关键字的使用方法。 在介绍之前需要明确下java中的每一个类的对象实例都有且只有一个锁(lock)和之相关联,synchronized关键字只作用于该锁,即可以认为

  • 本文向大家介绍Java中synchronized关键字修饰方法同步的用法详解,包括了Java中synchronized关键字修饰方法同步的用法详解的使用技巧和注意事项,需要的朋友参考一下 Java的最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问。 每一个用synchronized关键字声明的方法都是临界区。在Java中,同一个对象的临界区,在同一时间只有一个允许被访