【问题标题】:What does 'synchronized' mean?“同步”是什么意思?
【发布时间】:2010-11-08 07:32:04
【问题描述】:

我对@9​​87654324@ 关键字的用法和意义有一些疑问。

  • synchronized 关键字的意义是什么?
  • 什么时候方法应该是synchronized
  • 在编程和逻辑上是什么意思?

【问题讨论】:

标签: java multithreading keyword synchronized


【解决方案1】:

Java 同步

volatile[About] => synchronized

Java 中的synchronized 块是多线程中的监视器。 synchronized 具有相同对象/类的块只能由单个线程执行,所有其他线程都在等待。当多个线程尝试更新同一个变量时,它可以帮助解决race condition 的情况。

Java 5 通过支持happens-before[About] 扩展synchronized

监视器的解锁(同步块或方法退出)发生在同一监视器的每个后续锁定(同步块或方法入口)之前。

下一步是java.util.concurrent

【讨论】:

    【解决方案2】:

    在java中为了防止多个线程操作一个共享变量,我们使用synchronized关键字。让我们通过以下示例来理解它:

    在示例中,我定义了两个线程并将它们命名为递增和递减。递增线程将共享变量 (counter) 的值增加与递减线程减少它的量相同的量,即增加 5000 倍(导致 5000 + 0 = 5000)和我们减少 5000 倍(导致 5000 - 5000 = 0)。

    没有synchronized关键字的程序:

    class SynchronizationDemo {
    
        public static void main(String[] args){
    
            Buffer buffer = new Buffer();                   
    
            MyThread incThread = new MyThread(buffer, "increment");
            MyThread decThread = new MyThread(buffer, "decrement"); 
    
            incThread.start();
            decThread.start();  
           
            try {
              incThread.join();
              decThread.join();
            }catch(InterruptedException e){ }
    
            System.out.println("Final counter: "+buffer.getCounter());
        }
    }
    
    class Buffer {
        private int counter = 0; 
        public void inc() { counter++; }
        public void dec() { counter--; } 
        public int getCounter() { return counter; }
    }
    
    class MyThread extends Thread {
    
        private String name;
        private Buffer buffer;
    
        public MyThread (Buffer aBuffer, String aName) {            
            buffer = aBuffer; 
            name = aName; 
        }
    
        public void run(){
            for (int i = 0; i <= 5000; i++){
                if (name.equals("increment"))
                    buffer.inc();
                else
                    buffer.dec();                           
            }
        }
    }
    

    如果我们运行上面的程序,我们期望缓冲区的值是相同的,因为将缓冲区增加和减少相同的数量会导致我们以正确的?开始的初始值。让我们看看输出:

    正如您所看到的,无论我们运行程序多少次,我们都会得到不同的结果,原因是每个线程同时操作counter。如果我们可以设法让一个线程首先增加共享变量,然后再减少它,反之亦然,那么我们将获得正确的结果,这正是通过添加 synchronized 关键字可以完成的结果@关键字在 Bufferincdec 方法之前,如下所示:

    带有synchronized关键字的程序:

    // rest of the code
    
    class Buffer {
        private int counter = 0; 
        // added synchronized keyword to let only one thread
        // be it inc or dec thread to manipulate data at a time
        public synchronized void inc() { counter++; }
        public synchronized void dec() { counter--; } 
        public int getCounter() { return counter; }
    }
    
    // rest of the code
    

    和输出:

    无论我们运行多少次,我们都会得到与 0 相同的输出

    【讨论】:

      【解决方案3】:

      synchronized 关键字可防止多个线程同时访问代码块或对象。 Hashtable 的所有方法都是synchronized,所以一次只能有一个线程执行其中任何一个。

      当使用HashMap 等非synchronized 构造时,您必须在代码中构建线程安全功能以防止出现一致性错误。

      【讨论】:

        【解决方案4】:

        这是来自The Java Tutorials的解释。

        考虑以下代码:

        public class SynchronizedCounter {
            private int c = 0;
        
            public synchronized void increment() {
                c++;
            }
        
            public synchronized void decrement() {
                c--;
            }
        
            public synchronized int value() {
                return c;
            }
        }
        

        如果countSynchronizedCounter 的一个实例,那么使这些方法同步有两个效果:

        • 首先,对同一对象的同步方法的两次调用不可能交错。当一个线程正在为一个对象执行同步方法时,所有其他为同一对象调用同步方法的线程都会阻塞(暂停执行),直到第一个线程处理完该对象。
        • 其次,当一个同步方法退出时,它会自动与同一对象的任何后续同步方法调用建立起之前的关系。这保证了对象状态的更改对所有线程都是可见的。

        【讨论】:

          【解决方案5】:

          Synchronized normal method 相当于 Synchronized statement(使用这个)

          class A {
              public synchronized void methodA() {
                  // all function code
              }
          
              equivalent to
          
              public void methodA() {
                  synchronized(this) {
                       // all function code
                  }
              } 
          }
          

          Synchronized static method 等价于Synchronized statement(使用类)

          class A {
              public static synchronized void methodA() {
                  // all function code
              }
          
              equivalent to
          
              public void methodA() {
                  synchronized(A.class) {
                       // all function code
                  }
              } 
          }
          

          同步语句(使用变量)

          class A {
              private Object lock1 = new Object();
          
              public void methodA() {
                  synchronized(lock1 ) {
                       // all function code
                  }
              } 
          }
          

          对于synchronized,我们同时拥有Synchronized MethodsSynchronized Statements。但是Synchronized MethodsSynchronized Statements很相似,所以我们只需要了解Synchronized Statements就可以了。

          => 基本上,我们会有

          synchronized(object or class) { // object/class use to provides the intrinsic lock
             // code 
          }
          

          这里有2个想法,有助于理解synchronized

          • 每个对象/类都有一个与之关联的intrinsic lock
          • 当线程调用synchronized statement 时,它会自动获取该synchronized statement's 对象的intrinsic lock,并在方法返回时释放它。只要一个线程拥有intrinsic lock没有其他线程可以获得SAME锁=>线程安全。

          => 当thread A 调用synchronized(this){// code 1} => 具有synchronized(this) 和所有synchronized normal method(类内)的所有块代码(类内)被锁定,因为SAME 锁定。它将在thread A unlock(“// code 1”完成)后执行。

          此行为类似于synchronized(a variable){// code 1}synchronized(class)

          SAME LOCK => 锁(不依赖于哪个方法?或者哪个语句?)

          使用同步方法还是同步语句?

          我更喜欢synchronized statements,因为它更具可扩展性。例如,以后只需要同步一部分方法。例如,你有 2 个同步方法,它们没有任何相互关联,但是当一个线程运行一个方法时,它会阻塞另一个方法(它可以通过使用 synchronized(a variable) 来阻止) .

          但是,应用同步方法很简单,代码看起来也很简单。对于某些类,只有一个同步方法,或者类中的所有同步方法彼此相关 => 我们可以使用synchronized method 使代码更短且易于理解

          注意

          (它与synchronized 无关,它是对象和类或非静态和静态之间的区别)。

          • 当您使用synchronized 或普通方法或synchronized(this)synchronized(non-static variable) 时,它将基于每个对象实例进行同步。
          • 当您使用synchronized 或静态方法或synchronized(class)synchronized(static variable) 时,它将基于类同步

          参考

          https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

          希望对你有帮助

          【讨论】:

            【解决方案6】:

            synchronized 关键字是关于不同线程读取和写入相同变量、对象和资源的全部内容。这不是 Java 中的一个小话题,但这里引用 Sun 的一句话:

            synchronized 方法可以实现一个简单的 防止线程的策略 干扰和记忆一致性 错误:如果一个对象是可见的 多个线程,所有读取或 写入该对象的变量是 通过同步方法完成。

            简而言之:当您有两个线程正在读取和写入同一个“资源”时,比如一个名为 foo 的变量,您需要确保这些线程以原子方式访问变量。如果没有synchronized 关键字,您的线程1 可能看不到线程2 对foo 所做的更改,或者更糟糕的是,它可能只更改了一半。这不会是你在逻辑上所期望的。

            同样,这在 Java 中是一个重要的话题。要了解更多信息,请在此处探索关于 SO 和 Interwebs 的主题:

            继续探索这些主题,直到 “Brian Goetz” 这个名字在你的大脑中与“并发” 一词永久关联。

            【讨论】:

            • 那么,基本上这个 Synchronized 关键字让你的方法线程安全?
            • 同步关键字是使您的代码线程安全的工具之一。仅在方法或变量本身上使用同步可能会或可能不会成功。对 Java 内存模型有基本的了解对于正确处理并发非常重要。
            • 除非您是 Brian Goetz(或者可能是 Jon Skeet),否则仅使用语言原语(同步的、易变的)几乎不可能使 Java 并发正确。对于初学者,请使用 java.util.concurrent 包并在此基础上进行构建。
            • 更清楚一点:同步方法不能从多个线程同时调用。
            • @dhfromkorea 不。完全不同。实际上,“序列化”是获取一个对象的过程,该对象可能存储在内存的不同位置,并将其“序列化”为一维字节数组。这是为了存储或传输。
            【解决方案7】:

            其他答案缺少的是一个重要方面:内存障碍。线程同步基本上由两个部分组成:序列化和可见性。我建议大家在谷歌上搜索“jvm 内存屏障”,因为它是一个重要且极其重要的主题(如果您修改由多个线程访问的共享数据)。完成后,我建议查看 java.util.concurrent 包的类,这些类有助于避免使用显式同步,这反过来有助于保持程序简单高效,甚至可能防止死锁。

            一个这样的例子是ConcurrentLinkedDeque。与command pattern 一起,它允许通过将命令填充到并发队列中来创建高效的工作线程——不需要显式同步,不会出现死锁,不需要显式 sleep(),只需通过调用 take() 来轮询队列。

            简而言之:“内存同步”在您启动线程、线程结束、读取 volatile 变量、解锁监视器(离开同步块/函数)等时隐式发生。这“同步”影响(在某种意义上“刷新”)所有在该特定操作之前完成的写入。在上述ConcurrentLinkedDeque 的情况下,文档“说”:

            内存一致性效果:与其他并发集合一样, 在将对象放入 ConcurrentLinkedDeque happen-before 访问后的操作 或从另一个 ConcurrentLinkedDeque 中删除该元素 线程。

            这种隐含的行为有点有害,因为大多数没有太多经验的 Java 程序员会因此而接受很多。然后在 Java 没有按照“应该”在生产环境中执行不同工作负载后突然发现这个线程——而且很难测试并发问题。

            【讨论】:

              【解决方案8】:

              什么是同步关键字?

              线程主要通过共享对字段和对象引用字段的访问来进行通信。这种通信形式非常高效,但会导致两种错误:线程干扰和内存一致性错误。防止这些错误所需的工具是同步。

              同步块或方法可防止线程干扰并确保数据一致。在任何时候,只有一个线程可以通过获取锁来访问同步块或方法(临界区)。其他线程将等待释放锁以访问临界区

              方法何时同步?

              当您将synchronized 添加到方法定义或声明时,方法会同步。您还可以在方法中同步特定的代码块。

              在程序和逻辑上是什么意思?

              这意味着只有一个线程可以通过获取锁来访问临界区。除非该线程释放该锁,否则所有其他线程将不得不等待获取锁。他们无权进入临界区而不获取锁。

              这是魔法无法做到的。识别应用程序中的关键部分并相应地保护它是程序员的责任。 Java 提供了一个框架来保护您的应用程序,但所有部分的保护位置和内容是程序员的责任。

              更多细节来自java文档page

              内在锁和同步:

              同步是围绕称为内部锁或监视器锁的内部实体构建的。内在锁在同步的两个方面都发挥着作用:强制对对象状态的独占访问和建立对可见性至关重要的先发生关系。

              每个对象都有一个与之关联的内在锁。按照惯例,需要对对象的字段进行独占和一致访问的线程必须在访问对象之前获取对象的内在锁,然后在完成后释放内在锁。

              线程在获得锁和释放锁之间被称为拥有内在锁。 只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程在尝试获得锁时会阻塞。

              当线程释放内在锁时,会在该操作与任何后续获取同一锁的操作之间建立起先发生关系。

              使方法同步有两个effects

              首先,同一对象上的同步方法的两次调用不可能交错。

              当一个线程正在为一个对象执行同步方法时,所有其他为同一对象调用同步方法的线程都会阻塞(暂停执行),直到第一个线程处理完该对象。

              其次,当一个同步方法退出时,它会自动与任何后续对同一对象的同步方法调用建立起之前的关系。

              这保证了对象状态的变化对所有线程都是可见的。

              寻找同步的其他替代方法:

              Avoid synchronized(this) in Java?

              【讨论】:

                【解决方案9】:

                同步只是意味着如果在特定对象上使用同步块,则多个线程与单个对象关联可以防止脏读和写。为了让你更清楚,让我们举个例子:

                class MyRunnable implements Runnable {
                    int var = 10;
                    @Override
                    public void run() {
                        call();
                    }
                
                    public void call() {
                        synchronized (this) {
                            for (int i = 0; i < 4; i++) {
                                var++;
                                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
                            }
                        }
                    }
                }
                
                public class MutlipleThreadsRunnable {
                    public static void main(String[] args) {
                        MyRunnable runnable1 = new MyRunnable();
                        MyRunnable runnable2 = new MyRunnable();
                        Thread t1 = new Thread(runnable1);
                        t1.setName("Thread -1");
                        Thread t2 = new Thread(runnable2);
                        t2.setName("Thread -2");
                        Thread t3 = new Thread(runnable1);
                        t3.setName("Thread -3");
                        t1.start();
                        t2.start();
                        t3.start();
                    }
                }
                

                我们创建了两个 MyRunnable 类对象,runnable1 与线程 1 共享,线程 3 & runnable2 仅与线程 2 共享。 现在,当 t1 和 t3 在没有使用同步的情况下启动时,PFB 输出表明线程 1 和 3 同时影响 var 值,而对于线程 2,var 有自己的内存。

                Without Synchronized keyword
                
                    Current Thread Thread -1 var value 11
                    Current Thread Thread -2 var value 11
                    Current Thread Thread -2 var value 12
                    Current Thread Thread -2 var value 13
                    Current Thread Thread -2 var value 14
                    Current Thread Thread -1 var value 12
                    Current Thread Thread -3 var value 13
                    Current Thread Thread -3 var value 15
                    Current Thread Thread -1 var value 14
                    Current Thread Thread -1 var value 17
                    Current Thread Thread -3 var value 16
                    Current Thread Thread -3 var value 18
                

                使用 Synchronzied,线程 3 在所有场景中都在等待线程 1 完成。获得了两个锁,一个在 runnable1 上由线程 1 和线程 3 共享,另一个在 runnable2 上仅由线程 2 共享。

                Current Thread Thread -1 var value 11
                Current Thread Thread -2 var value 11
                Current Thread Thread -1 var value 12
                Current Thread Thread -2 var value 12
                Current Thread Thread -1 var value 13
                Current Thread Thread -2 var value 13
                Current Thread Thread -1 var value 14
                Current Thread Thread -2 var value 14
                Current Thread Thread -3 var value 15
                Current Thread Thread -3 var value 16
                Current Thread Thread -3 var value 17
                Current Thread Thread -3 var value 18
                

                【讨论】:

                • 同步的意义远不止于此:它对内存屏障有深远的影响。
                【解决方案10】:

                好吧,我想我们已经有足够的理论解释了,所以考虑一下这段代码

                public class SOP {
                    public static void print(String s) {
                        System.out.println(s+"\n");
                    }
                }
                
                public class TestThread extends Thread {
                    String name;
                    TheDemo theDemo;
                    public TestThread(String name,TheDemo theDemo) {
                        this.theDemo = theDemo;
                        this.name = name;
                        start();
                    }
                    @Override
                    public void run() {
                        theDemo.test(name);
                    }
                }
                
                public class TheDemo {
                    public synchronized void test(String name) {
                        for(int i=0;i<10;i++) {
                            SOP.print(name + " :: "+i);
                            try{
                                Thread.sleep(500);
                            } catch (Exception e) {
                                SOP.print(e.getMessage());
                            }
                        }
                    }
                    public static void main(String[] args) {
                        TheDemo theDemo = new TheDemo();
                        new TestThread("THREAD 1",theDemo);
                        new TestThread("THREAD 2",theDemo);
                        new TestThread("THREAD 3",theDemo);
                    }
                }
                

                注意:只要前一个线程的执行没有完成,synchronized 就会阻止下一个线程对方法 test() 的调用。线程一次可以访问这个方法。如果没有synchronized,所有线程都可以同时访问这个方法。

                当一个线程调用对象的同步方法'test'(这里对象是'TheDemo'类的一个实例)它获取该对象的锁,任何新线程不能调用同一对象的任何同步方法只要因为先前获得锁的线程不会释放锁。

                当调用类的任何静态同步方法时,也会发生类似的事情。线程获取与类关联的锁(在这种情况下,任何线程都可以调用该类实例的任何非静态同步方法,因为该对象级锁仍然可用)。只要当前持有锁的线程没有释放类级锁,任何其他线程将无法调用该类的任何静态同步方法。

                同步输出

                THREAD 1 :: 0
                THREAD 1 :: 1
                THREAD 1 :: 2
                THREAD 1 :: 3
                THREAD 1 :: 4
                THREAD 1 :: 5
                THREAD 1 :: 6
                THREAD 1 :: 7
                THREAD 1 :: 8
                THREAD 1 :: 9
                THREAD 3 :: 0
                THREAD 3 :: 1
                THREAD 3 :: 2
                THREAD 3 :: 3
                THREAD 3 :: 4
                THREAD 3 :: 5
                THREAD 3 :: 6
                THREAD 3 :: 7
                THREAD 3 :: 8
                THREAD 3 :: 9
                THREAD 2 :: 0
                THREAD 2 :: 1
                THREAD 2 :: 2
                THREAD 2 :: 3
                THREAD 2 :: 4
                THREAD 2 :: 5
                THREAD 2 :: 6
                THREAD 2 :: 7
                THREAD 2 :: 8
                THREAD 2 :: 9
                

                不同步的输出

                THREAD 1 :: 0
                THREAD 2 :: 0
                THREAD 3 :: 0
                THREAD 1 :: 1
                THREAD 2 :: 1
                THREAD 3 :: 1
                THREAD 1 :: 2
                THREAD 2 :: 2
                THREAD 3 :: 2
                THREAD 1 :: 3
                THREAD 2 :: 3
                THREAD 3 :: 3
                THREAD 1 :: 4
                THREAD 2 :: 4
                THREAD 3 :: 4
                THREAD 1 :: 5
                THREAD 2 :: 5
                THREAD 3 :: 5
                THREAD 1 :: 6
                THREAD 2 :: 6
                THREAD 3 :: 6
                THREAD 1 :: 7
                THREAD 2 :: 7
                THREAD 3 :: 7
                THREAD 1 :: 8
                THREAD 2 :: 8
                THREAD 3 :: 8
                THREAD 1 :: 9
                THREAD 2 :: 9
                THREAD 3 :: 9
                

                【讨论】:

                • @SantiIglesias “完成”?没有。此示例演示了synchronized 的锁定行为,但忽略了内存一致性。
                • @Stu Thompson 内存一致性是锁定的结果
                • @DheerajSachan 按照这个逻辑,使用 ReentrantLock 会导致内存一致性。它没有。
                • @boltup_im_coding : start() 方法将线程置于“RUNNABLE”状态,这意味着它已准备好执行或已经执行。可能会发生另一个处于 Runnable 状态的线程(通常但不一定具有更高优先级)会跳过队列并开始执行。在上面的例子中,线程 3 恰好在线程 2 之前获得 CPU。
                • @DheerajSachan 一切都很好,但您可以删除 SOP 类并重构代码。
                【解决方案11】:

                synchronized 表示在多线程环境中,具有synchronized 方法/块的对象不允许两个线程访问synchronized 的方法/块同时编码。这意味着一个线程无法读取,而另一个线程更新它。

                第二个线程将等到第一个线程完成执行。开销是速度,但优点是保证数据的一致性。

                如果您的应用程序是单线程的,synchronized 块不会提供任何好处。

                【讨论】:

                  【解决方案12】:

                  概述

                  Java 中的 Synchronized 关键字与线程安全有关,即当多个线程读取或写入同一个变量时。
                  这可以直接(通过访问同一个变量)或间接(通过使用使用另一个访问相同变量的类的类)。

                  synchronized关键字用于定义一个代码块,多个线程可以安全地访问同一个变量。

                  更深入

                  在语法方面,synchronized 关键字将 Object 作为其参数(称为锁定对象),然后是 { block of code }

                  • 当执行遇到此关键字时,当前线程会尝试“锁定/获取/拥有”(任您选择)锁定对象,并在锁定后执行相关的代码块被收购了。

                  • 保证对同步代码块内的变量的任何写入对于使用相同锁对象类似地执行同步代码块内的代码的每个其他线程都是可见的。

                  • 一次只有一个线程可以持有锁,在此期间所有其他试图获取相同锁对象的线程将等待(暂停它们的执行)。当执行退出同步代码块时,锁将被释放。

                  同步方法:

                  在方法定义中添加synchronized关键字等于将整个方法体包装在同步代码块中,锁对象this(例如方法) 和ClassInQuestion.getClass() (用于类方法)

                  - 实例方法是没有static 关键字的方法。
                  - 类方法是具有static 关键字的方法。 p>

                  技术

                  如果没有同步,则无法保证读取和写入的顺序,可能会给变量留下垃圾。
                  (例如,一个变量可能以一个线程写入的一半位结束,并且一半的位由另一个线程写入,使变量处于两个线程都没有尝试写入的状态,而是两者的结合。)

                  在另一个线程读取它之前(挂钟时间)在一个线程中完成写入操作是不够的,因为硬件可能已经缓存了变量的值,而读取线程将看到缓存的值而不是什么写给它。

                  结论

                  因此,在 Java 的情况下,您必须遵循 Java 内存模型以确保不会发生线程错误。
                  换句话说:使用同步、原子操作或在后台为您使用它们的类.

                  来源

                  http://docs.oracle.com/javase/specs/jls/se8/html/index.html
                  Java® 语言规范,2015-02-13

                  【讨论】:

                  • 对不起,但我有这个例子,我不明白意思:` Integer i1 = Arrays.asList(1,2,3,4,5).stream().findAny() 。得到(); synchronized(i1) { Integer i2 = Arrays.asList(6,7,8,9,10) .parallelStream() .sorted() .findAny().get(); System.out.println(i1+" "+i2); }` 1. 为什么你在第一个实例上调用了块,而这个调用对代码没有影响? 2. 第二个实例将是线程安全的,尽管在第一个实例上调用了块?
                  • @Adryr83 如果您有任何问题,您可以通过发布新问题来提问。但是既然我们在这里,我会尽力解析(你的问题有点难以理解)。从我对那段代码的了解来看,它似乎不包含任何需要同步的东西。这是断章取义的。建议:如果可以的话,尝试将代码分成更小的单独部分,然后搜索有关这些部分的答案。尝试理解小而孤立的问题比尝试找出一大块代码要容易得多。
                  【解决方案13】:

                  synchronized是Java中的一个关键字,用于在多线程环境中使关系发生在关系之前,以避免内存不一致和线程干扰错误。

                  【讨论】:

                    【解决方案14】:

                    同步简单意味着没有两个线程可以同时访问块/方法。当我们说类的任何块/方法是同步的时,这意味着一次只有一个线程可以访问它们。在内部,尝试访问它的线程首先会对该对象进行锁定,只要该锁定不可用,其他线程就无法访问该类实例的任何同步方法/块。

                    请注意,另一个线程可以访问同一对象的未定义为同步的方法。线程可以通过调用来释放锁

                    Object.wait()
                    

                    【讨论】:

                      【解决方案15】:

                      可以将它想象成一种旋转栅门,就像您在足球场上发现的那样。想要进入的人是平行的,但在十字转门处,他们是“同步的”。一次只能有一个人通过。所有想要通过的人都会这样做,但他们可能必须等到他们可以通过。

                      【讨论】:

                      • 显示器就像夜店里的保镖。
                      【解决方案16】:

                      synchronized关键字使线程在进入方法时获取锁,这样只有一个线程可以同时执行该方法(对于给定的对象实例,除非是静态方法)。

                      这通常被称为使类线程安全,但我想说这是一种委婉说法。虽然同步确实可以保护 Vector 的内部状态不被破坏,但这通常对 Vector 的用户没有多大帮助。

                      考虑一下:

                       if (vector.isEmpty()){
                           vector.add(data);
                       }
                      

                      即使涉及的方法是同步的,因为它们是单独锁定和解锁的,两个不幸的定时线程可以创建一个包含两个元素的向量。

                      因此,实际上,您还必须在应用程序代码中进行同步。

                      因为方法级别的同步 a) 在不需要时很昂贵,b) 在需要同步时不够,所以现在有不同步的替换(在 Vector 的情况下为 ArrayList)。

                      最近,并发包已发布,其中包含许多处理多线程问题的巧妙实用程序。

                      【讨论】:

                        【解决方案17】:

                        根据我的理解,同步基本上意味着编译器围绕您的方法编写了一个 monitor.enter 和 monitor.exit。因此,它可能是线程安全的,具体取决于它的使用方式(我的意思是,您可以使用非线程安全的同步方法编写对象,具体取决于您的类所做的事情)。

                        【讨论】:

                          猜你喜欢
                          • 2014-02-24
                          • 1970-01-01
                          • 2011-12-12
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2011-02-05
                          • 1970-01-01
                          相关资源
                          最近更新 更多