继承Thread类和实现Runnable接口的对比

1、采用继承Thread类方法的特点

优势:编写简单,如果需要访问当前的线程,只需要使用this,并可以在run()方法中调用其他线程的方法;

劣势:线程已经继承了Thread类,不能继承其他的父类

package test02;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MoveButtonWindow extends JFrame implements ActionListener{
    private JButton startButton;
    private JButton stopButton;
    private JButton exitButton;
    private JButton rightButton;
    private JButton leftButton;
    MoveToRight right;
    MoveToLeft left;
    
    //构造方法
    public MoveButtonWindow(){
    	//设置窗口标题
    	setTitle("线程测试");
    	
    	//创建面板
    	JPanel centerPanel=new JPanel();
    	JPanel controlPanel=new JPanel();
    	add(centerPanel,BorderLayout.CENTER);
    	add(controlPanel,BorderLayout.SOUTH);
    	
    	//创建按钮
    	startButton =new JButton("开始");
    	this.startButton.addActionListener(this);
    	
    	stopButton=new JButton("停止");
    	this.stopButton.addActionListener(this);
    	
    	exitButton=new JButton("退出");
    	this.exitButton.addActionListener(this);
    	
    	controlPanel.add(startButton);
    	controlPanel.add(exitButton);
    	controlPanel.add(stopButton);
    	
    	//定义centerPanel的布局,并添加按钮组件
    	//分别创建两个能够移动的按钮
    	centerPanel.setLayout(null);
    	centerPanel.setBackground(Color.black);
    	rightButton=new JButton("向右移动");
    	rightButton.setBackground(Color.yellow);
    	rightButton.setBounds(0, 5, 100, 30);
    	leftButton=new JButton("向左移动");
    	leftButton.setBackground(Color.red);
        leftButton.setBounds(395, 90, 100, 30);
        centerPanel.add(leftButton);
        centerPanel.add(rightButton);
        
        //新建控制按钮移动的线程right和left,处于新建状态
        right=new MoveToRight(rightButton);
        left=new MoveToLeft(leftButton);
        //设置窗口的一些属性
    	setBounds(100,100,500,200);
    	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	this.setResizable(false);
    	setVisible(true);
    	validate();
    	/*验证这个容器和它的所有子组件。
    	验证一个容器意味着布局它的子组件。
    	布置相关的变化,比如设置组件的边界,或者将一个组件添加到容器,容器会自动失效。
    	注意容器的祖先也可能无效(见组件。无效细节。)因此,恢复层次结构的有效性,
    	validate()方法应该调用层次结构的最顶层无效的容器。*/
    	
    }
   

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource()==this.startButton){
			//如果线程right死亡了,则重新给线程分配实体
			if(!right.isAlive()){
				right=new MoveToRight(rightButton);
			}
			//如果线程left死亡了,则重新给线程分配实体'
			if(!left.isAlive()){
				left=new MoveToLeft(leftButton);
			}
			right.start();
			left.start();
			
		}
		//如果点击通知按钮则结束线程
		else if(e.getSource()==this.stopButton){
			right.setBoo(false);
			left.setBoo(false);
		}
		//如果点击退出则退出应用程序
		else if(e.getSource()==this.exitButton){
			right.setBoo(false);
			left.setBoo(false);
			System.exit(0);
		}
	}
	 public static void main(String[] args){
	    	new MoveButtonWindow();
	    }
    
}
package test02;

import javax.swing.JButton;

public class MoveToLeft extends Thread{
	private JButton button;
	boolean boo=true;
	public MoveToLeft(JButton button){
		this.button=button;
		
	}
	public void run(){
		while(true){
			int x=button.getBounds().x;
			x=x-5;
		    if(x>400){
		    	x=5;
		    }
		    button.setLocation(x,90);
		    try{
		    	//调用sleep方法让线程暂停0.2秒
		    	Thread.sleep(200);
		    } catch (InterruptedException e){
		    	e.printStackTrace();
		    }
		    //结束当前线程
		    if(!boo){
		    	return;
		    }
		}		
	}
	public boolean isBoo(){
		return boo;
	}
	public void setBoo(boolean boo){
		this.boo=boo;
	}
}

package test02;

import java.io.IOException;

import javax.swing.JButton;

public class MoveToRight extends Thread{
	private JButton button;
	boolean boo=true;
	public MoveToRight(JButton button){
		this.button=button;
		
	}
	public void run(){
		while(true){
			int x=button.getBounds().x;
			x=x+5;
		    if(x>400){
		    	x=5;
		    }
		    button.setLocation(x,5);
		    try{
		    	//调用sleep方法让线程暂停0.2秒
		    	Thread.sleep(100);
		    } catch (InterruptedException e){
		    	e.printStackTrace();
		    }
		    //结束当前线程
		   if(!boo){
		    	return;
		    }
		}		
	}
	public boolean isBoo(){
		return boo;
	}
	public void setBoo(boolean boo){
		this.boo=boo;
	}
}


2、采用实现Runnable方法的特点

优势:实现了Runnable接口的类,还可以extends 其他的类,多个线程共享一个target对象,适合多线程用来处理同一份资源;

劣势:编程访问线程时,需要调用Thread.currentThread()方法

package test03;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MoveButtonWindow extends JFrame implements ActionListener,Runnable{
	private JButton startButton;
	private JButton stopButton;
	private JButton exitButton;
	private JButton rightButton;
	private JButton leftButton;
	Thread right;
	Thread left;
	boolean boo =true;
	public MoveButtonWindow(){
		setTitle("线程测试");
		
		JPanel centerPanel=new JPanel();
		JPanel controlPanel=new JPanel();
		add(centerPanel,BorderLayout.CENTER);
		add(controlPanel,BorderLayout.SOUTH);
		
		startButton=new JButton("开始");
		startButton.addActionListener(this);
		stopButton=new JButton("停止");
		stopButton.addActionListener(this);
		exitButton=new JButton("退出");
	    exitButton.addActionListener(this);
		controlPanel.add(this.startButton);
		controlPanel.add(this.stopButton);
		controlPanel.add(this.exitButton);
		
		
		rightButton=new JButton("向右移动");
		
		leftButton=new JButton("向左移动");
		
		centerPanel.add(rightButton);
		centerPanel.add(leftButton);
		//创建线程right和left,当前窗口的对象为target,线程处于新建状态
		right=new Thread(this);
		left=new Thread(this);
		
		//设置窗口的一些属性
		setBounds(100,100,500,200);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setResizable(false);
		setVisible(true);
		validate();
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
      new MoveButtonWindow();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==this.startButton){
			if(!right.isAlive()){
				right=new Thread(this);
			}
			if(!left.isAlive()){
				left=new Thread(this);
			}
			//设置标标记变量为true;
			boo=true;
			right.start();
			left.start();
		}
		else if(e.getSource()==this.stopButton){
		  boo=false;
		  
		}
		else if(e.getSource()==this.exitButton){
			boo=false;
			System.exit(0);
		}
		
		
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		//判断当前线程是right线程
		while(true){
		if(Thread.currentThread()==right)
		{
			int x=this.rightButton.getBounds().x;
			x=x+6;
            if(x>400){
            	x=6;
            }
            rightButton.setLocation(x,5);
            try{
    			Thread.sleep(100);
    		   }
    		catch(InterruptedException e){
    			e.printStackTrace();
    		}  
	     }  
		else if(Thread.currentThread()==left){
			int x=this.leftButton.getBounds().x;
			x=x-6;
            if(x<20){
            	x=395;
            }
            leftButton.setLocation(x,90);
            try{
    			Thread.sleep(100);
    		   }
    		catch(InterruptedException e){
    			e.printStackTrace();
    		}  
		}
		//如果线程boo为false,则结束进程,线程进入死亡状态
		
		if(!boo){
			return;
		}
	}

}
}

(代码有点繁琐)

你可能感兴趣的:(继承Thread类和实现Runnable接口的对比)