认识线程和创建线程

目录

1.认识多线程

1.1线程的概念

1.2进程和线程

1.2.1进程和线程用图描述关系

 1.2.2进程和线程的区别

1.3Java 的线程和操作系统线程的关系 

 2.创建线程

2.1继承 Thread 类

 2.2实现 Runnable 接口

 2.3匿名内部类创建 Thread 子类对象

2.4匿名内部类创建 Runnable 子类对象

2.5lambda 表达式创建 Runnable 子类对象 


1.认识多线程

1.1线程的概念

引入线程:进程虽然可以很好的实现并发编程,但在进行频繁的进程创建和销毁的过程中开销比较大(体现在资源的申请和释放上)。所以就发明了比进程更轻量的线程。

线程与进程相比:

(1)创建线程比创建进程更快 .
(2)销毁线程比销毁进程更快 .
(3)调度线程比调度进程更快 .
线程具体是什么?
  一个线程就是一个 " 执行流 ". 每个线程之间都可以按照顺序执行自己的代码 . 多个线程之间 " 同时 " 执行 着多份代码.

1.2进程和线程

1.2.1进程和线程用图描述关系
1.进程是包含线程的 . 每个进程至少有一个线程存在,即主线程。
2.进程和进程之间不共享内存空间 . 同一个进程的线程之间共享同一个内存空间 .
 1.2.2进程和线程的区别

(高频面试题)

1.进程是包含线程的。

2.每个线程就是一个 独立的"执行流",可以单独执行一些代码,并参与到CPU的调度(状态,上下文,优先级,记账信息,每个线程都有自己的一份)

3.每个进程都有自己的资源,进程中的线程共用一份资源(内存空间和文件描述符表)

(2)与(3)说明:

进程是系统分配资源的最小单位,线程是系统调度的最小单位。

4.进程与进程之间不会相会影响,但 线程与线程之间会相会影响。如果一个进程中的某个线程抛出异常,可能会导致进程中的所有线程都异常终止。

1.3Java 的线程和操作系统线程的关系 

1.线程是操作系统中的概念 . 操作系统内核实现了线程这样的机制 , 并且对用户层提供了一些 API 供用户使用(例如 Linux pthread ).
2. Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装 .

注意:

(1)线程与线程之间可能会相互干扰,产生逻辑bug,引起线程安全。

(2)线程不是越多越好,线程太多调度开销可能会非常明显。


 2.创建线程

2.1继承 Thread

(1)继承 Thread 来创建一个线程类

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("这里是线程运行的代码");
    }
}

此处 run()不需要手动调动,在线程创建好之后JVM会自动调用执行(回调函数)。

(2)创建 MyThread 类的实例

MyThread t = new MyThread();

创建出的实例才是真线程。 

 (3)调用 start 方法启动线程 

t.start(); // 线程开始运行

此时才会真正调用系统API,在系统内核中创建出线程(执行run())。

 为啥要在系统内核中创建出线程?

因为程序有时需要对软硬件资源进行操作。

完整示例:

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
        while(true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("MyThread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 进程创建第一个线程时开销最大,之后的线程开销都比较小,但不是0,main线程其实是第一个线程。

一直循环…… 

 当有多个线程,它们的执行顺序是不确定的。


 使用 jconsole 命令观察线程

我们可以使用jdk自带的工具 jconsole查看当前Java进程中所有的线程

第一步,找到jdk

第二步,点进去,找到里面的bin文件点进去

第三步,在bin文件夹里搜索jconsole 

第四步,找到你所创建进程点击线程进行查看


 2.2实现 Runnable 接口

(1) 实现 Runnable 接口

class MyRunnable implements Runnable {
    @Override
    public void run () {
        System . out . println ( " 这里是线程运行的代码 " );
  }
}

2) 创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 参数.

Thread t = new Thread(new MyRunnable());

(3) 调用 start 方法

t.start(); // 线程开始运行 

 完整示例:

public class ThreadDemo2 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start();
        while(true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        while(true){
            System.out.println("MyRunnable");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
这种写法其实就是把线程和要执行的任务进行了解耦合。
对比上面两种方法 :
1.继承 Thread , 直接使用 this 就表示当前线程对象的引用 .
2.实现 Runnable 接口 , this 表示的是 MyRunnable 的引用 . 需要使用 Thread.currentThread()

 2.3匿名内部类创建 Thread 子类对象

// 使用匿名类创建 Thread 子类对象
Thread t1 = new Thread () {
    @Override
    public void run () {
        System . out . println ( " 使用匿名类创建 Thread 子类对象 " );
  }
};

  完整示例:

public class ThreadDemo3 {
    public static void main(String[] args) {
        Thread t=new Thread(){
            @Override
            public void run() {
                while (true){
                    System.out.println("使用匿名类创建 Thread 子类对象");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
        while(true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2.4匿名内部类创建 Runnable 子类对象

// 使用匿名类创建 Runnable 子类对象
Thread t2 = new Thread ( new Runnable () {
    @Override
    public void run () {
        System . out . println ( " 使用匿名类创建 Runnable 子类对象 " );
  }
});

  完整示例:

public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("使用匿名类创建Runnable子类对象");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        t.start();
        while(true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2.5lambda 表达式创建 Runnable 子类对象 

 lambda就是让方法看上去脱离类,单独存在。

// 使用 lambda 表达式创建 Runnable 子类对象
Thread t3 = new Thread (() -> System . out . println ( " 使用匿名类创建 Thread 子类对象 " ));
Thread t4 = new Thread (() -> {
    System . out . println ( " 使用匿名类创建 Thread 子类对象 " );
});

  完整示例:

  public static void main(String[] args) {
        Thread t=new Thread(() -> {
            while(true){
                System.out.println("使用匿名类创建Runnable子类对象");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        while(true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

都看到这了,不如关注一下,给个免费的赞 

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值