如何创建线程详解(二)

1、在 Windows 操作系统中创建进程

  在 windows 操作系统中,我们创建一个进程通常就是打开某个应用软件,这便在电脑中创建了一个进程。更原始一点的,我们在命令提示符中来做(我们以打开记事本这个进程为例):

  第一步:windows+R,输入cmd,打开 cmd 命令提示符

      

  第二步:在命令提示符中输入 notepad,按 Enter 键便会弹出记事本应用软件

      

 

 PS:常用的windows 应用软件命令

    1、regedit:打开注册表编辑器

    2、control:打开控制面板

    3、msconfig:打开系统配置

    4、gpedit.msc:打开本地组策略

    5、explorer:打开资源管理器

    6、taskmgr:任务管理器

    7、logoff:直接注销计算机

    8、osk:打开屏幕键盘

    9、calc:打开计算器

    10、mspaint:调出画图软件

    11、dxdiag:查看电脑详细配置信息

    12、mstsc:打开远程桌面连接

    13、systeminfo:查看计算机基本信息

    14、notepad:打开记事本

      

 

2、在 Java 中创建进程

 

第一种方法:通过 Runtime 类的 exec() 方法来创建进程

?


1

2

public class Runtime

extends Object<br>①、表示当前进程所在的虚拟机实例,每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口。<br>②、由于任何进程只会运行与一个虚拟机实例当中,即只会产生一个虚拟机实例(底层源码采用 单例模式)<br>③、当前运行时可以从getRuntime方法获得。 

   

 

  由上面源码可以看到,构造器私有化了,即外部我们不能 new 一个新的 Runtime 实例,而内部给了我们一个获取 Runtime 实例的方法 getRuntime() 。

 

通过 Runtime 类创建一个 记事本的 进程

?


1

2

3

4

5

6

7

8

9

public class ProcessTest {

     

    public static void main(String[] args) throws Exception {

        Runtime run = Runtime.getRuntime();

        //打开记事本

        run.exec("notepad");

    }

 

}

  

  

第二种方法:通过 ProcessBuilder 创建线程

?


1

2

3

public final class ProcessBuilder

extends Object<br>①、此类用于创建操作系统进程。

②、每个ProcessBuilder实例管理进程属性的集合。 start()方法使用这些属性创建一个新的Process实例。 start()方法可以从同一实例重复调用,以创建具有相同或相关属性的新子进程。

?


1

2

3

4

5

6

7

8

9

public class ProcessTest {

     

    public static void main(String[] args) throws Exception {

        //打开记事本

        ProcessBuilder pBuilder = new ProcessBuilder("notepad");

        pBuilder.start();

    }

 

}

  

 

  

3、在 Java 中创建线程

第一种方法:继承 Thread 类

?


1

2

3

public class Thread

extends Object

implements Runnable  

 

步骤:1、定义一个线程类 A 继承于 java.lang.Thread 类

   2、在 A 类中覆盖 Thread 类的 run() 方法

   3、在 run() 方法中编写需要执行的操作

   4、在 main 方法(线程)中,创建线程对象,并启动线程

      创建线程类:A类 a = new A()类;

      调用 start() 方法启动线程:a.start();

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

package com.ys.thread;

 

class Thread1 extends Thread{

    @Override

    public void run() {

        for(int i = 0 ; i < 10 ;i++){

            System.out.println("播放音乐"+i);

        }

    }

}

 

public class ThreadTest {

    public static void main(String[] args) {

        for(int i = 0 ; i < 10 ; i++){

            System.out.println("玩游戏"+i);

            if(i==5){

                Thread1 th1 = new Thread1();

                th1.start();

            }

        }

    }

 

}

  结果:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

玩游戏0

玩游戏1

玩游戏2

玩游戏3

玩游戏4

玩游戏5

玩游戏6

玩游戏7

玩游戏8

玩游戏9

播放音乐0

播放音乐1

播放音乐2

播放音乐3

播放音乐4

播放音乐5

播放音乐6

播放音乐7

播放音乐8

播放音乐9

  注意:我们看结果,并不是出现 5 个先打游戏,然后在播放音乐,这是线程调度的结果,两个线程同时在争抢 CPU 的资源,即最后的结果,前面5个打游戏的必然先出现的,后面的啥时候出现播放音乐就看 CPU 怎么调度了,这是随机的。我们不能干涉。

 

 

第二种方法:实现 Runnable 接口

?


1

2

@FunctionalInterface

public interface Runnable

  

1、Runnable接口应由任何类实现,其实例将由线程执行。 该类必须定义一个无参数的方法,称为run 。
2、该接口旨在为希望在活动时执行代码的对象提供一个通用协议。此类整个只有一个 run() 抽象方法

 

步骤:1、定义一个线程类 A 实现于 java.lang.Runnable 接口(注意:A类不是线程类,没有 start()方法,不能直接 new A 的实例启动线程)

   2、在 A 类中覆盖 Runnable 接口的 run() 方法

   3、在 run() 方法中编写需要执行的操作

   4、在 main 方法(线程)中,创建线程对象,并启动线程

      创建线程类:Thread t = new Thread( new A类() ) ;

      调用 start() 方法启动线程:t.start();

 

 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Runnable1 implements Runnable{

    @Override

    public void run() {

        for(int i = 0 ; i < 10 ;i++){

            System.out.println("播放音乐"+i);

        }

    }

}

 

public class RunnableTest {

    public static void main(String[] args) {

        for(int i = 0 ; i < 10 ; i++){

            System.out.println("玩游戏"+i);

            if(i==5){

                Thread th1 = new Thread(new Runnable1());

                th1.start();

            }

        }

    }

 

}

  

 

 第三种方法:使用匿名内部类创建线程

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public static void main(String[] args) {

        for(int i = 0 ; i < 10 ; i++){

            System.out.println("玩游戏"+i);

            if(i==5){

                new Thread(new Runnable() {

                    @Override

                    public void run() {

                        for(int i = 0 ; i < 10 ;i++){

                            System.out.println("播放音乐"+i);

                        }

                    }

                }).start();

            }

        }

    }

  

 

注意:

1、启动线程是调用 start() 方法,而不是 调用 run() 方法。

  解析:run()方法:在本线程内调用run()方法,和其他方法没有什么区别,可以重复多次调用;

     start()方法:启动一个线程,实际上还是调用该Runnable对象的run()方法。

     打开 Thread 类的源码,start()方法里面有一句:

        private native void start0();  //native 关键字:本地程序调用    

    native关键字指的是Java本地接口调用,即是使用Java调用本地操作系统的函数功能完成一些特殊的操作,而这样的代码开发在Java中几乎很少出现,因为Java的最大特点是可移植性,如果一个程序 只能在固定的操作系统上使用,那么可移植性就将彻底丧失,多线程的实现一定需要操作系统的支持,那么start0()方法实际上就和抽象方法很类似,没有方法体,而是交给JVM 去实现,即在windows下的JVM可能使用A方法实现start0(),在linux下的JVM可能使用B方法实现start0(),在调用时并不会关心具体是何方式实现了start0()方法,只会关心最终的操作结果,交给 JVM去匹配了不同的操作系统。

 

2、不能多次启动同一个线程,即多次调用 start() 方法,只能调用一次,否则报错:

  

 

时间: 2024-11-08 18:23:49

如何创建线程详解(二)的相关文章

Java线程详解(二)

Java线程:新特征-线程池 线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源. 在使用线程池之前,必须知道如何去创建一个线程池,在Java5中,需要了解的是java.util.concurrent.Executors类的API,这个类提供大量创建连接池的静态方法,是必须掌握的. Java通过Executor

POSIX 线程详解(2-线程创建和销毁)

算法旨在用尽可能简单的思路解决问题,理解算法也应该是一个越看越简单的过程,当你看到算法里的一串概念,或者一大坨代码,第一感觉是复杂,此时不妨从例子入手,通过一个简单的例子,并编程实现,这个过程其实就可以理解清楚算法里的最重要的思想,之后扩展,对算法的引理或者更复杂的情况,对算法进行改进.最后,再考虑时间和空间复杂度的问题. 了解这个算法是源于在Network Alignment问题中,图论算法用得比较多,而对于alignment,特别是pairwise alignment, 又经常遇到maxim

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

python线程详解

#线程状态 #线程同步(锁)#多线程的优势在于可以同时运行多个任务,至少感觉起来是这样,但是当线程需要共享数据时,可能存在数据不同步的问题. #threading模块#常用方法:'''threading.currentThread():返回当前的线程变量threading.enumerate():返回一个包含正在运行的线程的list,正在运行指:线程启动后,结束前,不包含启动前和终止后的线程threading.activeCount():返回正在运行的线程数量,与len(threading.en

POSIX 线程详解(1-概述)

线程是有趣的 线程类似于进程.如同进程,线程由内核按时间分片进行管理.在单处理器系统中,内核使用时间分片来模拟线程的并发执行,这种方式和进程的相同.而在多处理器系统中,如同多个进程,线程实际上一样可以并发执行. 那么为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可以读或写声明过的全局变量.如果曾用 fork() 编写过重要代码,就会认识到这个工具的重要性.为什么呢?虽然 fork() 允

POSIX 线程详解(3-互斥量:&quot;固定加锁层次&quot;/“试加锁-回退”)

有时一个互斥量是不够的: 比如: 当多个线程同时访问一个队列结构时,你需要2个互斥量,一个用来保护队列头,一个用来保护队列元素内的数据. 当为多线程建立一个树结构时,你可能需要为每个节点设置一个互斥量. 同时使用多个互斥量会导致复杂度的增加 最坏的情况就是死锁的发生,即两个线程分别锁住一个互斥量而等待对方的互斥量. 多互斥量可能导致死锁: 如果可以在独立的数据上使用两个分离的互斥量,那么就应该这么做.这样,通过减少线程必须等待其他线程完成数据操作的时间. 如果数据独立,则某个特定函数就不太可能经

C#网络编程基础之进程和线程详解

在C#的网络编程中,进程和线程是必备的基础知识,同时也是一个重点,所以我们要好好的掌握一下. 一:概念 首先我们要知道什么是"进程",什么是"线程",好,查一下baike. 进程:是一个具有一定独立功能的程序关于某个数据集合的一次活动.它是操作系统动态执行的基本单元, 在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元. 线程:是"进程"中某个单一顺序的控制流. 关于这两个概念,大家稍微有个印象就行了,防止以后被面试官问到. 二:进程

“全栈2019”Java多线程第二十五章:生产者与消费者线程详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第二十五章:生产者与消费者线程详解 下一章 "全栈2019"Java多线程第二十六章:同步方法生产者与消费者线程 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"

KafkaProducer Sender 线程详解(含详细的执行流程图)

目录 1.Sender 线程详解 2.RecordAccumulator 核心方法详解 温馨提示:本文基于 Kafka 2.2.1 版本. 上文 <源码分析 Kafka 消息发送流程> 已经详细介绍了 KafkaProducer send 方法的流程,该方法只是将消息追加到 KafKaProducer 的缓存中,并未真正的向 broker 发送消息,本文将来探讨 Kafka 的 Sender 线程. @(本节目录) 在 KafkaProducer 中会启动一个单独的线程,其名称为 "