JAVA基础之多线程基础(一)

1 什么是进程,什么是线程?
  • 进程:进程是一个应用程序。
  • 线程:是一个进程中的执行场景或者一个执行单元。
2 对于java程序来说,当在Dos命令窗口中输入:java HelloWorld回车之后,会先启动JVM,而JVM就是一个进程。JVM再启动一个主线程调用mian方法。同时再启动一个垃圾回收线程负责看护,回收垃圾。

因此,现在的java程序至少有两个线程并发。一个是垃圾回收线程,一个是执行main方法的主线程。

3 进程与线程的关系
  1. 进程A和进程B的内存独立不共享。
  2. 线程A和线程B:在java语言中,线程A和线程B堆内存和方法区共享内存,栈内存独立不共享,一个线程一个栈。
  3. 假设启动10个线程,会有10个栈空间,每个栈和每个栈之间互不干扰,各自执行各自的,这就是多线程并发。
4 思考:

使用了多线程机制之后,main方法结束,是不是有可能程序也不会结束?
main方法结束知识主线程结束了,主栈空了,其他的栈(线程)可能还在压栈弹栈。

5 对于单核CPU来说,真的可以做到多线程并发吗?

例如:t1执行t1的,t2执行t2的,互不影响。
不能做到真正的多线程并发,但是可以做到给人一种“多线程并发”的感觉。
对于单核cpu来说,在某个时间点上实际上只能处理一件事情,但是由于cpu的处理速度极快,多个线程之间频繁切换执行,给人的感觉是多个事情同时在做。

6 java语言中,实现线程有两种方式:

java支持多线程机制,并且java已经将多线程实现了,我们只需要继承就行了。

方式一:编写一个类,直接继承java.lang.Thread,重写run方法

public class ThreadTest02 {
    public static void main(String[] args) {
        //主线程
        //新建一个分支线程对象
        MyThread myThread = new MyThread();
        //启动线程start();只是为了开启一个新的栈空间
        myThread.start();//启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成后瞬间结束
        for(int i=0;i<100;i++){
            System.out.println("这里是主线程"+i);
        }

    }
}

class MyThread extends Thread{
    //分支线程
    @Override
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("分支线程"+i);
        }
    }
}

myThread.start()解读
  • 作用:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码在完成任务后,瞬间就结束了。同时线程也就启动成功了。
  • 启动成功后:自动调用run()方法,并且run方法在分支栈的底部(压栈),run()方法在分支栈底部,main方法在主栈的底部。run和main都是平级的。【如果直接用myThread调用run方法,不会启动分支线程,此时还是单线程】。

方式二:编写一个类,实现java.lang.Runnable接口,实现run()方法;

import java.rmi.server.UnicastRemoteObject;

public class ThreadTest03 {
    public static void main(String[] args) {
        MyRunnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();
        for(int i=0;i<10000;i++){
            System.out.println("这里是主线程eeeezzz"+i);
        }

    }
}

class MyRunnable implements Runnable{
    @Override
    public void run(){
        for(int i=0;i<10000;i++){
            System.out.println("这里是分支"+i);
        }

    }
}

总结:这两种方式第二种好一些。接口除了实现接口,还能继承别的类,更灵活。

7 线程的生命周期

在这里插入图片描述

线程对象:
  1. 怎么获取线程对象?
    Thread.currentThread();
  2. 怎么获取线程对象的名字?
    t1.getName(“t1”)
  3. 怎么修改线程对象?
    t1.setName(“t1”)
线程sleep:staic void sleep(Long millis)

1.静态方法
2.参数是毫秒
3.让当前线程进入休眠状态,进入阻塞状态,放弃占有的cpu时间片,让给其他线程

public class ThreadTest06 {
    public static void main(String[] args) throws InterruptedException {
        Thread t= new MyRunnable();
        //Thread t = new Thread(r);
        t.start();
        //让当前线程进入休眠状态,出现在main方法中,让main方法睡眠,并不是线程t睡眠
        t.sleep(1000 * 10);//这里让main线程休息10秒执行接下来的代码,不影响分支线程的执行
        System.out.println("主线程main");


    }
    static class MyRunnable extends Thread{
        @Override
        public void run(){
            for (int i = 0;i<10;i++){
                try {
                    Thread.sleep(1000);//每隔一秒打印一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("分支线程"+i);
            }

        }
    }
}

唤醒睡眠的线程(不是中断线程的执行)

t.interrupt();//依靠java的异常处理机制

强行终止线程的执行
  1. 方法一:stop();会存在数据丢失的现象
  2. 方法二: 设置flag标记
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值