通过继承Thread类实现线程与实现Runnable接口实现线程有什么区别

时间:2022-10-23 17:31:44
//下面这个程序是:继承线程类通过线程同步方法实现同步会出错,通过线程同步块实现同步却没有错。

//请问这二者有何区别??

class SellThread extends Thread
{  
   static Object obj=new Object();
   static int tickets=50;
   public void run()
   {  
    while(tickets>0) 
     {  
      /*synchronized(obj)//线程同步块
       {
       if(tickets>0)
       {
       System.out.println(Thread.currentThread

().getName( )+" sell tickets:"+tickets);
             tickets=tickets-1;  
              try
              {
              Thread.sleep(1);
              }
             catch(Exception e)
             {
              e.printStackTrace();
             }
           }*/  
        sell();
      }        
   } 
 
  public synchronized void sell()//线程同步方法
   {        
   if(tickets>0)
{  
     System.out.println(Thread.currentThread().getName( )+" sell 

tickets:"+tickets);
     tickets--; 
    }              
   }
}

class TicketsSystem_this_obj
{
  public static void main(String args[])
   {  
     SellThread st1=new SellThread(); 
     SellThread st2=new SellThread(); 
     SellThread st3=new SellThread(); 
     SellThread st4=new SellThread(); 
     st1.start();
     st2.start();
   st3.start();
   st4.start();
     /* try
         {
         Thread.sleep(10);
          }
         catch(Exception e)
         {
          e.printStackTrace();
         }*/   
  }
}

4 个解决方案

#1


这样子的sell不是每个线程各自的sell么?
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的

#2


一个类只能有一个父类,就是单继承。如果这个类已经有父类,就只能通过实现接口来实现了。

#3


参考楼上的。

#4


1、由于java的单继承机制,你继承Thread类的话,那么这个自定义线程类就不能再继承其它的类;而接口可以实现多个,所以通过实现Runnable接口来实现的话,那么这个实现类还可以继承其它的类
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:

package Lesson8;

class SellThread extends Thread {

private Tickets tickets;

public SellThread(Tickets tickets)
{
this.tickets=tickets;
}

public void run() {
while (tickets.getNum()>0) {
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tickets.sell();
}
}
}

public class Demo3 {
public static void main(String args[]) {
Tickets tickets=new Tickets(20);
SellThread st1 = new SellThread(tickets);
SellThread st2 = new SellThread(tickets);
SellThread st3 = new SellThread(tickets);
SellThread st4 = new SellThread(tickets);
st1.start();
st2.start();
st3.start();
st4.start();
}
}

class Tickets
{
private int num=0;

public int getNum()
{
return num;
}
public Tickets(int num)
{
this.num=num;
}

public synchronized void sell()// 线程同步方法
{
if (num > 0) {
System.out.println(Thread.currentThread().getName()
+ " sell tickets:" + num);
num--;
}
}
}

通过继承Thread类实现线程与实现Runnable接口实现线程有什么区别

#1


这样子的sell不是每个线程各自的sell么?
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的

#2


一个类只能有一个父类,就是单继承。如果这个类已经有父类,就只能通过实现接口来实现了。

#3


参考楼上的。

#4


1、由于java的单继承机制,你继承Thread类的话,那么这个自定义线程类就不能再继承其它的类;而接口可以实现多个,所以通过实现Runnable接口来实现的话,那么这个实现类还可以继承其它的类
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:

package Lesson8;

class SellThread extends Thread {

private Tickets tickets;

public SellThread(Tickets tickets)
{
this.tickets=tickets;
}

public void run() {
while (tickets.getNum()>0) {
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tickets.sell();
}
}
}

public class Demo3 {
public static void main(String args[]) {
Tickets tickets=new Tickets(20);
SellThread st1 = new SellThread(tickets);
SellThread st2 = new SellThread(tickets);
SellThread st3 = new SellThread(tickets);
SellThread st4 = new SellThread(tickets);
st1.start();
st2.start();
st3.start();
st4.start();
}
}

class Tickets
{
private int num=0;

public int getNum()
{
return num;
}
public Tickets(int num)
{
this.num=num;
}

public synchronized void sell()// 线程同步方法
{
if (num > 0) {
System.out.println(Thread.currentThread().getName()
+ " sell tickets:" + num);
num--;
}
}
}

通过继承Thread类实现线程与实现Runnable接口实现线程有什么区别