线程基础(一)

活动地址:CSDN21天学习挑战赛

一.并发与并行的概念

1.程序:一个固定逻辑与数据的集合就是程序 例如 俄罗斯方块 贪吃蛇
2.cpu:中央处理器 主要用于协调程序与硬件的工作

那什么是并发与并行?
先来一张图浅显了解一下并发和并行的区别吧。
在这里插入图片描述

大体上的解释是:
并发(又称高并发):是同一个时间段执行两个,或者两个以上程序的,单核cpu交互(上面所说的时间片轮转是一种)的执行,由于cpu切换的速度很快,逻辑上我们任务并发是同时执行多个任务,实际上是交替执行

例子:两个队伍的人在一个窗口打菜。

并行:在同一时刻,执行两个或者是多个程序的时候,多核cpu同时执行(现象的电脑都是多核cpu)

例子:多个人在多个咖啡机前排队。

在这里插入图片描述

二.线程与进程

概念:
进程运行在内存中的程序就是进程.

每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程

线程: 通向cpu的执行的路径就是线程。

线程又分为单线程和多线程
单线程:只有一条通向cpu的执行的路径
多线程:多条通向cup的执行的路径
注意:
1.一个进程中能包含多个线程
2.一个线程只能存在一个进程中。
3.任务管理器里关闭的那个玩意就叫做进程

在这里插入图片描述

多线程的进程运行的流程图
在这里插入图片描述

三. 主线程与子线程

在这里插入图片描述

3.1主线程:

主方法中,例如运行main方法函数的线程

负责管理子线程,即子线程的启动、挂起、停止等等操作

public class HelloWorld {
    public static void main(String[] args) {

        Thread mainThread = Thread.currentThread();
        System.out.println("我是主线程");
    }
}

3.2子线程:

只能是理解为由主线程负责管理,即主线程负责启动,挂起,停止的线程为子线程

3.3进程,主线程,子线程的关系图

在这里插入图片描述

四.线程的三种创建方法

4.1 第一种 继承Thread重写run方法

步骤:

1.定义一个类去继承Thread
2.重写run()方法,执行线程的操作
3.实例化这个线程类的独享
4.调用start()方法,开启线程

 public class MyThread extends Thread{ 
 	@Override 
 	public void run() { 
 		for (int i=1;i<=10;i++){
  			System.out.println(i); 
 		 } 
 	 } 
  }

测试类


public class Testhuang {
    public static void main(String[] args) {
        //实例化对象
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

输出结果:
在这里插入图片描述

4.2第二种 实现Runnable接口

步骤:

1.定义一个类 实现 Runnable
2.实现run()
3.实例化线程对象 Thread 传递一个参数 Runnable 的实现类
4.调用方法开启线程 start()

线程定义类

public class MyRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "\t" + i);
        }
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) {
        //实例化Runnable对象的实现类
      MyRunnable r = new MyRunnable(); //实例化线程类
        Thread th = new Thread(r); //开启线程
         th.start();
    }
}

结果
在这里插入图片描述

4.3第三种 实现Callable接口

步骤

1.定义一个类实现接口 Callable
2.重写call()方法
3.实例化 任务对象 FutureTask 构建一个Callable的实现类
4.实例化线程对象 Thread 构建一个任务对象
5.开启线程
6.调用任务对象的get() 获取其返回值

实现线程类

public class MyCallAble implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Integer sum = 0;
        for (int i = 0; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallAble call = new MyCallAble();
        FutureTask<Integer> f = new FutureTask<>(call);
        Thread t = new Thread(f);
        t.start();
        Integer c = f.get();
        System.out.println(c);
    }
}

结果
在这里插入图片描述

4.4 最常用的创建线程的方式

使用Runnable的匿名内部类来创建线程

public class Testhuang {
    public static void main(String[] args) { 
        //第一种方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }).start();
        
        
        //第二种方式
        new  Thread(){
            @Override
            public  void  run(){
                System.out.println(Thread.currentThread().getName());
            }
        }.start();
    }
}

结果
在这里插入图片描述

4.5 线程调度的方式

线程调度的方式有两种

1.分配式调度:多个线程执行任务的时间,都是评价分配,每一个线程执行的周期都是相同的
2.抢占式调度:线程的优先级越高,获取cpu执行权越高,线程抢到cpu的概率就越搞,优先执行的概率就越高,而我们的java中的多线程就是抢占式调度

在这里插入图片描述

例子:
创建线程类

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            try {
                //sleep方法是休眠方法,这里间隔0.1s
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //.getName方法获取当前线程的名称
            System.out.println(Thread.currentThread().getName() + "\t" + i);
        }
    }
}

测试类:

public class Testhuang {
    public static void main(String[] args) {
        //开启第一个线程
        MyThread th1 = new MyThread();
        th1.start();

        //开启第二个线程
        MyThread th2 = new MyThread();
        System.out.println(th2);
    }
}

在这里插入图片描述

4.5线程的内存图

在这里插入图片描述

4.7 线程的常见方法

4.7.1 获取线程名

方法名作用
public final String getName()返回该线程的名称
public static Thread currentThread()返回对当前正在执行的线程对象的引用

线程创建类

public class MyThread extends Thread {
    @Override
    public  void  run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + "\t" + i);
        }
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread th = new MyThread();
        th.start();
        for (int i = 1; i <= 10; i++) {
           System.out.println(Thread.currentThread().getName() + "\t" + i);
        }
    }
}

结果
在这里插入图片描述

4.7.2 线程休眠

方法名作用
public static void sleep(long millis)线程休眠

线程创建类

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 60; i >= 1; i--) {
            System.out.println("还剩下" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread th = new MyThread();
        th.start();

    }
}

结果

在这里插入图片描述

4.7.3 守护线程

方法名作用
public final void setDaemon(boolean on)设置为守护线程
public final boolean isDaemon()测试该线程是否为守护线程

线程创建类

public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            //休眠五秒
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            OutputStream is = new FileOutputStream("3.txt");
            is.write(97);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) {
        //实例化线程对象 
        MyThread my = new MyThread();
        //设置为守护线程 
        my.setDaemon(true);
        //获取其状态 
        System.out.println(my.isDaemon());
        my.start();
        try {
            Thread.sleep(6000);
        } catch (
                InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果

显示开启了守护线程

4.7.4 设置线程的优先级

4.7.4.1 常量
常量名作用
public static final int MAX_PRIORITY线程可以具有的最高优先级
public static final int MIN_PRIORITY线程可以具有的最低优先级
public static final int NORM_PRIORITY分配给线程的默认优先级

在这里插入图片描述
注意点

1.线程的最高优先级10最低优先级1,范围1-10
2.线程优先级越高表示获取cpu执行权越大即被执行的概率越高,但是并不一定会执行 ,因为java是抢占式调度

4.7.4.2 方法
方法名作用
public final int getPriority()返回的是线程的优先级
public final void setPriority(int newPriority)更改线程的优先级

线程创建类

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println(getName() + "\t" + i);
        }
    }
}

测试类

public class Testhuang {
    public static void main(String[] args) {
        //实例化第一个线程
        MyThread t = new MyThread();
        t.setPriority(8);
        t.start(); //
        // 实例化第二个线程
        MyThread th = new MyThread();
        th.setPriority(Thread.MAX_PRIORITY);
        th.start();
    }
}

结果
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值