代码之家  ›  专栏  ›  技术社区  ›  user2514421

多线程

  •  2
  • user2514421  · 技术社区  · 9 年前

    我有一个关于多线程的想法,但我从未尝试过。所以,当我看到我的应用程序在工作时…我还没有看到任何扩展线程的类创建 Thread 所以 synchronized 当两个对象试图同时访问一个变量时使用关键字。我们使用synchronized来避免冲突。

    例子:

    public class Test {
    
        private static int count = 0;
    
        public static synchronized void incrementCount() {
            count++;
        }
    } 
    

    如果测试类被对象使用,那么添加 同步的,同步的 incrementcount() 。但当你不延长 线 Runnable 那么写作有什么用 同步的,同步的 .

    3 回复  |  直到 9 年前
        1
  •  2
  •   Community CDub    8 年前

    Synchronized不适用于线程或Runnables,它用于由多个线程访问的数据结构,以确保每个线程都以不破坏其数据的方式访问它们。您自己的示例是一个基本的例子,其中计数以一种不安全的方式递增( using ++, see this question ),因此它需要锁定,以确保一次只有一个线程可以增加它。

    如果有其他代码访问count,则还需要进行同步,以便对count进行更新。如果您所做的只是递增一个计数器,那么使用这样的类更有意义 java.util.concurrent.atomic.AtomicInteger ,您可以完全不使用synchronized关键字。

    为了使使用synchronized有意义,它确实假设存在多个线程。即使您自己的代码没有创建新线程,也可能存在多个线程调用您的代码的情况(例如在servlet容器中,容器管理线程池并为每个传入请求分配一个线程)。

        2
  •  1
  •   Ravindra babu    9 年前

    类不需要 extend Thread implements Runnable 将其方法标记为同步,以防止多线程访问

    您的类可能是其他线程类的参数,该线程类可能有多个实例。为了提供强大的数据一致性,您必须保护代码的关键部分;数据

    只需将代码示例更改如下。

    我正在演示“ synchronized “在对象级别而不是类级别( static synchronized )

    class Test {
        private int count = 0;
        public void incrementCount() {
            count++;
            System.out.println("Count:"+count);
        }
    } 
    class MyRunnable implements Runnable{
        private Test test = null;
        public MyRunnable(Test t){
            this.test = t; 
        }
        public void run(){
            test.incrementCount();
        }
    }
    public class SynchronizedDemo{
        public static void main(String args[]){
            Test t = new Test();
            for ( int i=0; i<10; i++){
                new Thread(new MyRunnable(t)).start();  
            }
        }
    }
    

    你的班级 Test 已作为参数传递给线程 MyRunnable 。现在您已经创建了多个线程实例。在没有 同步的,同步的 关键字,输出不可预测,如下所示。

    java SynchronizedDemo
    Count:2
    Count:3
    Count:2
    Count:7
    Count:6
    Count:5
    Count:4
    Count:10
    Count:9
    Count:8
    

    如果我改变

    public void incrementCount() {
    

    public synchronized void incrementCount() {
    

    输出为:

    Count:1
    Count:2
    Count:3
    Count:4
    Count:5
    Count:6
    Count:7
    Count:8
    Count:9
    Count:10
    

    另一方面,您可以将方法设置为 静态同步的 . That means lock is maintained at class level instead of object level.

    查看oracle文档 page 以便更好地理解。

    缺少“”的代码演示 静态同步的 "

    class Test {
        private static int count = 0;
        public static void incrementCount() {
            count++;
            System.out.println("Count:"+count);
        }
    } 
    class MyRunnable implements Runnable{
        private Test test = null;
        public MyRunnable(Test t){
            this.test = t; 
        }
        public void run(){
            test.incrementCount();
        }
    }
    public class SynchronizedDemo{
        public static void main(String args[]){
            for ( int i=0; i<10; i++){
                Test t = new Test();
                new Thread(new MyRunnable(t)).start();  
            }
        }
    }
    

    输出:

    Count:5
    Count:4
    Count:3
    Count:2
    Count:10
    Count:9
    Count:8
    Count:7
    Count:6
    

    制作后

    public static void incrementCount() {
    

    ppublic static synchronized void incrementCount() {
    

    输出:

    计数:1
    计数:2
    计数:3
    计数:4
    计数:5
    计数:6
    计数:7
    计数:8
    计数:9
    计数:10
    

    在本例中,与前面不同,我们创建了10个不同的 测验 实例。

        3
  •  0
  •   AMACB    9 年前

    i++ ,尽管看起来像一条指令,但实际上是多条指令:

    1. 将临时变量设置为 1+i .
    2. 设置变量 i 到临时变量。

    但是,假设执行 我++ 在步骤之后中断 1 ,并且中断线程也调用 我++ 。然后,这将发生:

    (假设 i=1 )

    1. 原始线程: 将临时变量1设置为 1+i 2 .
    2. 中断线程: 将临时变量2设置为 i+1 而且 2.
    3. 中断线程: 设置 到临时变量2。现在 i=2
    4. 原始线程: 设置 到临时变量1。现在 i=2

    问题是如果 我++ 被调用两次,应该是 3 2. .


    A. synchronized void 会锁定变量 直到整个 void 完成执行。例如:

    1. 原始线程: 将临时变量1设置为 1+i 2. 。锁定变量 .
    2. 中断线程: 尝试将临时变量2设置为 i+1 ,但由于变量锁定而等待
    3. 原始线程: 设置 到临时变量1。现在 i=2 。变量 现在已解锁。
    4. 中断线程: “注意” 已解锁,因此它将临时变量2设置为 i+1 这是 3. .
    5. 中断线程: 3. ,这是预期行为。

    同步空隙 s本质上临时锁定变量,以避免混淆程序的执行。