并发编程(一):线程概念和常用方法

一、并发和并行的区别

引用 Rob Pike 的一段描述:
并发(concurrent)是同一时间应对(dealing with)多件事情的能力
并行(parallel)是同一时间动手做(doing)多件事情的能力
例子
家庭主妇做饭、打扫卫生、给孩子喂奶,她一个人轮流交替做这多件事,这时就是并发
家庭主妇雇了个保姆,她们一起这些事,这时既有并发,也有并行(这时会产生竞争,例如锅只有一口,一
个人用锅时,另一个人就得等待)
雇了3个保姆,一个专做饭、一个专打扫卫生、一个专喂奶,互不干扰,这时是并行

二、创建线程

1、new Thread()

package com.bear.demo1;

import com.sun.media.jfxmedia.logging.Logger;

/** 创建线程
 * @author LiuShanshan
 * @version V1.0
 * @Description
 */
public class CreateThrad {
    public static void main(String[] args) {
        // thread创建线程1
        Thread threaddemo1 = new Thread("线程1thread方式创建") {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        };
        threaddemo1.start();
        System.out.println("主线程");
    }
}

2、Runnable配合Thread

    public static void RunnableInit(){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("第二个线程测试");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

3、futureTask配合Thread

    public static void FutureTaskInit(){
        FutureTask futureTask = new FutureTask(new Runnable() {
            @Override
            public void run() {
                System.out.println("FutureTask执行");
            }
        }, "gogo");
        Thread thread = new Thread(futureTask);
        thread.start();
    }

使用到的花里胡哨的东西其实都是都要用到Thread类,只要看Thread类里面可以用什么参数就可以了,这里的FutureTask也是继承了Runnable

三、原理之线程运行

1、栈与栈祯

我们都知道 JVM 中由堆、栈、方法区所组成,其中栈内存是给谁用的呢?其实就是线程,每个线程启动后,虚拟
机就会为其分配一块栈内存。

  • 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
  • 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

2、线程的上下文切换

因为以下一些原因导致 cpu 不再执行当前的线程,转而执行另一个线程的代码

  • 线程的 cpu 时间片用完
  • 垃圾回收
  • 有更高优先级的线程需要运行
  • 线程自己调用了 sleep、yield、wait、join、park、synchronized、lock 等方法

四、方法

1、start与run

2、sleep与yield :

sleep:当前线程休眠,释放cpu

3、join方法 :线程调用join方法,这个线程就会执行完成,一直到销毁

注意:join和sleep连用:线程执行调用join方法的线程,遇到sleep,释放cpu,让其他线程执行

4、interrupt:interrupt()方法只是改变中断状态,不会中断一个正在运行的线程(也就是说会给当前线程打一个标记,当前线程堵塞变成继续往下执行,但是如果要结束当前线程的话需要自己去处理)

5、LockSupport.park():堵塞改线程,类似如sleep,都会释放cpu资源。

6、主线程和守护线程:守护线程:只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束

上一篇:k8s集群配置搭建skywalking


下一篇:基于kubernetes实现链路监控