一:概念理解
多线程
程序:静态的代码,应用软件执行的蓝本
进程:程序的一次动态执行过程,对应了从代码加载、执行至执行完毕的一个完整过程。
线程:比进程更小的执行单位,一个进程在执行过程当中能够产生多个线程。jvm
操做系统中使用分时管理各个进程,按时间片轮流执行每一个进程。Java 的多线程就是在操做系统每次分时给 Java 程序一个时间片的 CPU 时间内,在若干独立的可控制的线程之间进行切换。
Java 程序从 main 方法开始执行,当 JVM 加载代码,发现 main 方法以后会启动一个线程,这个线程是主线程,在 main 方法执行的过程当中启动的线程称为该程序的其余线程。当发现程序中包含主线程和其余线程时,JVM 会在主线程和其余线程之间轮流切换,保证每一个线程都有机会使用 CPU 资源。
二:代码分析
ide
/** * 分析程序: * 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+" "); } } }
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(); //建立线程t一、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(); } }