使用 Runnable 和派生 Thread 类的线程之间存在意外的行为差异

发布于 2024-10-21 00:39:58 字数 1562 浏览 2 评论 0原文

问:我需要对以下代码的输出进行详细解释...使用 runnable 接口创建的线程和通过扩展线程类直接创建的线程有什么区别...???

Q1:

public class BalanceChecker1{
    public static void main(String [] args) {
        RunnableClass runnableClass=new RunnableClass();
        new Thread(runnableClass).start();
        new Thread(runnableClass).start();
    }
}

class RunnableClass implements Runnable{
    Bean bean=new Bean();
    public void run(){
        synchronized(bean){
            bean.incBalance();
        }
    }
}

class Bean{
    private int balance=0;
    public void incBalance(){
        balance++;
        System.out.println(" The thread name "+Thread.currentThread().getName());
        System.out.println(" The balance is "+balance);
    }
}

输出:

 The thread name Thread-0
 The balance is 1
 The thread name Thread-1
 The balance is 2

Q2:

public class BalanceChecker1{
    public static void main(String [] args){
        new specialThread().start();
        new specialThread().start();
    }
}
class specialThread extends Thread{
    Bean bean=new Bean();
    public void run(){
        synchronized(bean){
            bean.incBalance();
        }
    }
}

class Bean{
    private int balance=0;
    public void incBalance(){
        balance++;
        System.out.println(" The thread name "+Thread.currentThread().getName());
        System.out.println(" The balance is "+balance);
    }
}

输出:

 The thread name Thread-0
 The thread name Thread-1
 The balance is 1
 The balance is 1

Q:I need a detailed explanation on the outputs of the following codes... What is the difference for the thread created using runnable interface and the thread created directly by extending thread class...???

Q1:

public class BalanceChecker1{
    public static void main(String [] args) {
        RunnableClass runnableClass=new RunnableClass();
        new Thread(runnableClass).start();
        new Thread(runnableClass).start();
    }
}

class RunnableClass implements Runnable{
    Bean bean=new Bean();
    public void run(){
        synchronized(bean){
            bean.incBalance();
        }
    }
}

class Bean{
    private int balance=0;
    public void incBalance(){
        balance++;
        System.out.println(" The thread name "+Thread.currentThread().getName());
        System.out.println(" The balance is "+balance);
    }
}

OUTPUT:

 The thread name Thread-0
 The balance is 1
 The thread name Thread-1
 The balance is 2

Q2:

public class BalanceChecker1{
    public static void main(String [] args){
        new specialThread().start();
        new specialThread().start();
    }
}
class specialThread extends Thread{
    Bean bean=new Bean();
    public void run(){
        synchronized(bean){
            bean.incBalance();
        }
    }
}

class Bean{
    private int balance=0;
    public void incBalance(){
        balance++;
        System.out.println(" The thread name "+Thread.currentThread().getName());
        System.out.println(" The balance is "+balance);
    }
}

OUTPUT:

 The thread name Thread-0
 The thread name Thread-1
 The balance is 1
 The balance is 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

折戟 2024-10-28 00:39:58

这两个示例之间的重要区别在于 Runnable 与扩展 Thread 中的(一个不相关的说明:几乎没有理由扩展< code>Thread,您几乎总是希望实现 Runnable

重要的区别在于,在第一个示例中,两个正在运行的线程共享一个公共的 Bean 对象。同步!这意味着对 incBalance() 的调用不能同时由两个线程执行,

在第二个示例中,它们每个都有一个单独的 Bean 对象。同步没有实际效果。

另请注意,不能保证您发布的输出:您可以在第二个示例中获得与第一个示例相同的输出(但是,您无法从第一个示例中获得第二个示例的混合输出) 。

The important difference between those two examples is not in Runnable vs. extending Thread (on an unrelated note: there's almost never a reason to extend Thread, you almost always want to implement Runnable.

The important difference is that in the first example both running threads share a common Bean object on which they synchronize! This means that the call to incBalance() can't be executed by both threads at once.

In the second example they have a separate Bean object each, so the synchronization has no practical effect.

Also note that the output you posted is not guaranteed: you could get the same output in the second example as in the first (you can't get the mixed output from the second example form the first, however).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文