使用 Runnable 和派生 Thread 类的线程之间存在意外的行为差异
问:我需要对以下代码的输出进行详细解释...使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这两个示例之间的重要区别在于
Runnable
与扩展Thread
中的不(一个不相关的说明:几乎没有理由扩展< code>Thread,您几乎总是希望实现Runnable
。重要的区别在于,在第一个示例中,两个正在运行的线程共享一个公共的
Bean
对象。同步!这意味着对incBalance()
的调用不能同时由两个线程执行,在第二个示例中,它们每个都有一个单独的
Bean
对象。同步没有实际效果。另请注意,不能保证您发布的输出:您可以在第二个示例中获得与第一个示例相同的输出(但是,您无法从第一个示例中获得第二个示例的混合输出) 。
The important difference between those two examples is not in
Runnable
vs. extendingThread
(on an unrelated note: there's almost never a reason to extendThread
, you almost always want to implementRunnable
.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 toincBalance()
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).