线程及synchronized锁的理解

程序、进程与线程

一:概念理解
 

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

 
       操作系统中使用分时管理各个进程,按时间片轮流执行每个进程。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();
    }
}

猜你喜欢

转载自blog.51cto.com/13416247/2334118