`
费文—jmiss
  • 浏览: 34922 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

线程基础总结

阅读更多

 

1.单线程与多线的区别:

单线程的特点:调用的函数一个随另一个函数的结束二开始,如:public void A(){  B(); C();},必须得B函数结束后,C()函数才开始,即函数按顺序调用。

多线程的特点:让多个函数并行执行,故与之单线程比较,多线程的优点:并行执行 节省时间


2.线程、进程、程序的区别:

一个进程包含一个或者多个线程的运行;线程是系统分配CPU运算时间的最小单位,线程之间可以进行数据交换,而进程一般不能;一个程序在处理不同数据集时成为不同的进程,程序是通过进程与数据产生联系的.一个进程肯定有一个与之对应的程序,而且只有一个.而一个程序有可能没有与之对应的进程(没有执行),也有可能有多个进程与之对应(运行在几个不同的数据集上).

  (主函数也是一个线程)

 


3.线程的实现

①继承Thread类实现线程

实现线程,就是用一个类继承Thread,重写Thread类中run()方法,在run()方法中实现实现要执行的方法,而后通过创建该类,调用Thread类的start()方法启动线程,由于run()方法不能传参,故只能在run()方法外面定义变量

 

 

/**
 * 统计线程,继承Thread
 * @author Administrator
 *
 */
public class Count extends Thread{
	
	
	int num;
	
	public Count(int num){
		this.num = num;
	}
	
	/**
	 * 重写run()
	 */
	@Override
	public void run(){
		
		
		countUtil();
		
		
	}
	
	
	

	/**
	 * 统计方法
	 */
	public void countUtil(){
		……
		
	}
	
}

 

 

	public static void main(String args[]){
		
		
		for(int i=0;i<3;i++){	
			//创建一个线程对象
			Count c1 = new Count(i);	
			
			c1.start();
			
		}
		
       }

 

 ②实现Runnable接口创建线程

  定义一个实现Runnable接口的类,实现它的run()方法,创建该类,将该类包装为Thread类,通过Thread类启动线程。

 

/**
 * 通过集成Runnable实现线程
 * 
 * @author Administrator
 * 
 */
public class Listener implements Runnable {
	private ArrayList<Ball> list;

	public Listener(ArrayList<Ball> list) {
		this.list = list;
	}

	public void run() {

		while (!Ball.isStop) {

			for (int i = 0; i < list.size() - 1; i++) {

				Ball b1 = list.get(i);
				Ball b2 = list.get(i + 1);

				System.out.println(b1.x0 + " " + b1.y0 + "<>" + b2.x0 + " "
						+ b2.y0);

			}

			try {

				Thread.sleep(1);
			} catch (Exception ef) {
				ef.printStackTrace();
			}

		}

	}

}

 

 

 

// 启动监视线程
Listener lis = new Listener(list);
Thread th=new Thread(lis);
th.start();
 

 

③以匿名内部类的方式创建线程

匿名内部类中的变量必须定义为final

 

/**
 * 以内部类的形式创建线程
 * @author lenovo
 *
 */
public class ThreadTest {
	
	public static void main(String args[]){
		
		ThreadTest tt=new ThreadTest();
		
		tt.startTheThread();
	}
	
	/**
	 * 启动线程的方法
	 */
	public void startTheThread(){
		
		java.lang.Runnable runner=new Runnable(){
			
			public void run(){
				
				……
				
				try{
					Thread.sleep(100);
				}catch(Exception ef){
					ef.printStackTrace();
				}
			}
		};
		
		//创建线程并启动
		Thread t=new Thread(runner);
		t.start();
	}

}
 

 

④继承TimerTask类实现线程的定时执行

调度TimerTask对象会定时运行java.util.Timer类。Timer类中有一个常用的方法:

public void schedule(TimerTask task, long delay ,long period)

(调度task对象在程序启动启动delay 毫秒后,每隔period执行一次)

 

 

import java.util.Timer;
import java.util.TimerTask;

/**
 * 继承TimerTask类实现线程的定时执行
 * @author lenovo
 *
 */
public class TimerTest extends TimerTask{

	public static void main(String args[]){
		//创建一个计时器对象
		Timer tim=new Timer();
		
		TimerTest tt=new TimerTest();
		//程序启动5秒后调度,每隔3秒调度一次
		tim.schedule(tt, 5000, 3000);
	}

	@Override
	//重写run()方法,作为线程运行时被调用
	public void run() {
		
	}
	
}
 

 

 

@Override:强制检测重写父类方法是否正确



4.线程的监听模式

为了实现对线程的监听,就要在创建一个监听线程,通过队列保存被监听的对象,在监听线程中就能得到被监听对象的属性,进而能对其进行修改。监听线程必须在被监听对象线程启动前启动。

 

// 通过匿名内部类创建监听器对象
		ActionListener alis = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				String command = e.getActionCommand();

				if (command.equals("开始")) {
					Ball.initBall();
					// 启动监视线程
					Listener lis = new Listener(list);
					Thread th=new Thread(lis);
					th.start();

					Ball b = new Ball(BallUI.this);// 传入窗体
					b.start();
					list.add(b);
				}
			}
		}
 

import java.util.ArrayList;

/**
 * 监视线程
 * 
 * @author Administrator
 * 
 */
public class Listener implements Runnable {
	private ArrayList<Ball> list;

	public Listener(ArrayList<Ball> list) {
		this.list = list;
	}

	public void run() {

		while (!Ball.isStop) {

			for (int i = 0; i < list.size() - 1; i++) {

				Ball b1 = list.get(i);
				Ball b2 = list.get(i + 1);

				System.out.println(b1.x0 + " " + b1.y0 + "<>" + b2.x0 + " "
						+ b2.y0);

			}

			try {

				Thread.sleep(1);
			} catch (Exception ef) {
				ef.printStackTrace();
			}

		}

	}

}
 

 

5.线程的控制

由于jdk中提供的线程的暂停、停止等方法存在安全隐患且已过时,我们必须通过自己编写一个线程控制机制。也就是通过改变循环的条件来实现。

 

/*
*实现对线程的控制
*/

public class Ball extends Thread {

	public static boolean isStop = false;// 是否停止
	public static boolean isPause = false;// 是否暂停

public void run() {
		move();
	}

	public void move() {
		while (!isStop) {
			while (!isPause) {

				……
				try {
					Thread.sleep(1000);// 沉睡时间,球移动位置的时间间隔
				} catch (Exception ef) {
					ef.printStackTrace();
				}

			}
			try {
				Thread.sleep(1);// 沉睡时间,暂停时的休眠
			} catch (Exception ef) {
				ef.printStackTrace();
			}
		}
	}

	/**
	 * 暂停线程的方法
	 */
	public static void pauseThread() {
		isPause = true;
	}

	/**
	 * 继续线程的方法
	 */
	public static void resumeThread() {
		isPause = false;
	}

	/**
	 * 停止线程的方法
	 */
	public static void stopThread() {
		isPause = true;
		isStop = true;
	}

	/**
	 * 停止线程的方法
	 */
	public static void initBall() {
		isPause = false;
		isStop = false;
	}
}

 (有几个循环就要try…catch几次,防止占用cpu过高)

 

if (command.equals("开始")) {
					Baffle.startThread();
					Ball.startThread();
					// 刷新面板
					javax.swing.SwingUtilities.updateComponentTreeUI(panel);

					Baffle bf = new Baffle(panel);
					panel.addKeyListener(bf);
					// 创建线程监听对象
					ThreadListener tl = new ThreadListener(panel, start,blist, bf);
					tl.start();

					bf.start();

					Ball b1 = new Ball(panel);
					b1.start();
					blist.add(b1);

					Ball b2 = new Ball(panel);
					b2.start();
					blist.add(b2);

					Ball b3 = new Ball(panel);
					b3.start();
					blist.add(b3);

					Ball b4 = new Ball(panel);
					b4.start();
					blist.add(b4);
					
					start.setText("暂停");
				}
				if (command.equals("暂停")) {
					Baffle.pauseThread();
					Ball.pauseThread();
					start.setText("继续");
				}
				if (command.equals("继续")) {
					Baffle.resumeThread();
					Ball.resumeThread();
					start.setText("暂停");
				}
				if (command.equals("停止")) {
					Baffle.stopThread();
					Ball.stopThread();
					start.setText("开始");
				}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics