`
NOthingAj
  • 浏览: 15419 次
社区版块
存档分类
最新评论

Java多线程总结

    博客分类:
  • Java
阅读更多

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

进程(英语:process)是计算机中已运行程序的实体。进程为曾经是分时系统的基本运作单位。

一个进程可以有很多线程,每条线程并行执行不同的任务。

 

(来自慕课网的代码实例)

主类:

 

import java.io.*;

public class Stage extends Thread {

	public static void main(String[] args) {
		new Stage().start();
	}

	public void run(){
		
		System.out.println("欢迎观看隋唐演义");

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}

		System.out.println("大幕徐徐拉开");
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		
		System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天黑地...");
		

		ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable(); 
		ArmyRunnable armyTaskOfRevolt = new ArmyRunnable();
		
		/**
		 * 创建两个线程
		 */
		Thread  armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军");
		Thread  armyOfRevolt = new Thread(armyTaskOfRevolt,"农民起义军");
		
		/**
		 * 启动线程,让军队开始作战
		 */
		armyOfSuiDynasty.start();
		armyOfRevolt.start();
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("正当双方激战正酣,半路杀出了个程咬金");
		
		Thread mrCheng = new KeyPersonThread();
		mrCheng.setName("程咬金");
		
		System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!");
		
		/**
		 * 停止前两个线程
		 */
		armyTaskOfSuiDynasty.keepRunning = false;
		armyTaskOfRevolt.keepRunning = false;
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		mrCheng.start(); // 开始第三个线程
				
		try {
			mrCheng.join(); // 新进程加入,join() 方法会在该线程结束之前一直占用CPU
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!");
		System.out.println("谢谢观看隋唐演义,再见!");
		
	}	
}

 辅助类:

 

class ArmyRunnable implements Runnable {

	volatile boolean keepRunning = true; // volatile 单独说明

	@Override
	public void run() {
		while(keepRunning){
			
			for(int i=0;i<5;i++){
				System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]");
				
				Thread.yield(); // yield() 方法单独说明
			}
					
		}
		
		System.out.println(Thread.currentThread().getName()+"结束了战斗!");

	}

}

class KeyPersonThread extends Thread {

	public void run(){
		System.out.println(Thread.currentThread().getName()+"开始了战斗!");
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+"左突右杀,攻击隋军...");
		}
		System.out.println(Thread.currentThread().getName()+"结束了战斗!");
	}
}

 

 join() 方法的详细说明:

 

(01) 在“主线程main”中通过 new ThreadA("t1") 新建“线程t1”。 接着,通过 t1.start() 启动“线程    t1”,并执行t1.join()。
(02) 执行t1.join()之后,“主线程main”会进入“阻塞状态”等待t1运行结束。“子线程t1”结束之后,会唤醒“主线程main”,“主线程”重新获取cpu执行权,继续运行。

 

 

 volatile 变量的说明:

 

1)(适用于Java所有版本)读和写一个volatile变量有全局的排序。也就是说每个线程访问一个volatile作用域时会在继续执行之前读取它的当前值,而不是(可能)使用一个缓存的值。(但是并不保证经常读写volatile作用域时读和写的相对顺序,也就是说通常这并不是有用的线程构建)。

2)(适用于Java5及其之后的版本)volatile的读和写建立了一个happens-before关系,类似于申请和释放一个互斥锁。

 

 yield() 方法的说明:

 

会使当前线程由执行状态变为让步状态,但不代表下次执行的线程必然是其它的线程,该方法执行后当前线程会处于竞争状态,因此下次执行的线程依然可能是上次执行的线程(这里假设各个线程优先级相同)。

 

  • 大小: 7.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics