程序、进程与线程

一:概念理解  

程序:静态的代码,应用软件执行的蓝本 进程:程序的一次动态执行过程,对应了从代码加载、执行至执行完毕的一个完整过程。 线程:比进程更小的执行单位,一个进程在执行过程中可以产生多个线程。

         操作系统中使用分时管理各个进程,按时间片轮流执行每个进程。Java 的多线程就是在操作系统每次分时给 Java 程序一个时间片的 CPU 时间内,在若干独立的可控制的线程之间进行切换。          Java 程序从 main 方法开始执行,当 JVM 加载代码,发现 main 方法之后会启动一个线程,这个线程是主线程,在 main 方法执行的过程中启动的线程称为该程序的其他线程。当发现程序中包含主线程和其他线程时,JVM 会在主线程和其他线程之间轮流切换,保证每个线程都有机会使用 CPU 资源。   二:代码分析  

/**
 * 分析程序:
 * 	1. JVM 首先将 CPU 资源分配给主线程,主线程在分配时执行了:
 * 		//创建线程
 *		SpeakHello speakHello = new SpeakHello();
 *		SpeakNiHao speakNiHao = new SpeakNiHao();
 *		//启动线程
 *		speakHello.start();
 *		speakNiHao.start();
 *	2. 开始执行 for 循环,for 循环为啥没执行完呢?
 *		主线程在使用 CPU 资源的时候执行了:
 *			speakHello.start();
 *			speakNiHao.start();
 *		所以 JVM 知道已经有三个线程需要轮流切换使用 CPU 资源
 *	3. speakNiHao.start() 的作用是通知 JVM: 咳咳咳,老子在等着你给我分配 CPU 资源
 * @author guozhenZhao
 * @date 2018年12月22日
 */
public class ThreadTest {
	//主程序(主线程)
	public static void main(String[] args) {
		//创建线程
		SpeakHello speakHello = new SpeakHello();
		SpeakNiHao speakNiHao = new SpeakNiHao();
		//启动线程
		speakHello.start();
		speakNiHao.start();
		
		for (int i = 1; i <= 20; i++) {
			System.out.print("大家好"+i+" ");
		}
	}
}

//线程一
class SpeakHello extends Thread{
	@Override
	public void run() {
		for (int i = 1; i <= 20; i++) {
			System.out.print("hello"+i+" ");
		}
	}
}

//线程二
class SpeakNiHao extends Thread{
	@Override
	public void run() {
		for (int i = 1; i <= 20; i++) {
			System.out.print("您好"+i+" ");
		}
	}
	
}

synchronized关键字的理解

 

package com.zgz.multi.sync001;

/**
 * 两种情况:
 * 一:
 * 	关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当作锁
 * 	所以代码中那个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的锁(lock)
 * 二:
 * 	在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占这个类)
 * @author guozhenZhao
 * @date 2018年12月22日
 */
public class MultiThread {
	private static int num = 0;
	
	public synchronized void printNum(String tag) {
		try {
			if(tag.equals("a")) {
				num = 100;
				System.out.println("tag a, set num over");
				Thread.sleep(1000);
			}else {
				num = 200;
				System.out.println("tag b, set num over");
			}
			
			System.out.println("tag: "+tag+", num=" + num);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//注意观察run方法输出顺序
	public static void main(String[] args) {
		//两个不同的对象
		final MultiThread m1 = new MultiThread();
		final MultiThread m2 = new MultiThread();
		
		//创建线程t1、t2
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				m1.printNum("a");
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				m2.printNum("b");
			}
		});
		
		//通知jvm,有线程在等待执行
		t1.start();
		t2.start();
	}
}