一、Java中关于应用程序和进程相关的概念

  在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过任务管理器查看)。Java采用的是单线程编程模型,即在我们自己的程序中如果没有主动创建线程的话,只会创建一个线程,通常称为主线程。但是要注意,虽然只有一个线程来执行任务,不代表JVM中只有一个线程,JVM实例在创建的时候,同时会创建很多其它的线程(比如垃圾收集器线程)。

  由于Java采用的是单线程编程模型,因此在进行UI编程时要注意将耗时的操作放在子线程中进行,以避免阻塞主线程(在UI编程时,主线程即UI线程,用来处理用户的交互事件)

二、Java中如何创建线程

  在Java中如果要创建线程的话,一般有两种方式:1)继承Thread类;2)实现Runnable接口。

  1、继承Thread类

  继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。

 class MyThread extends Thread {
private static int num = 0; public MyThread() {
num++; } @Override
public void run() {
System.out.println("主动创建的第" + num + "个线程");
}
}

  创建好了自己的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。注意,不是调用run方法启动线程,run方法只是定义需要执行的任务。如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。

 package com.meng.javalanguage.thread.test;

 public class MyThreadTest {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
} class MyThread extends Thread {
private static int num = 0; public MyThread() {
num++;
} @Override
public void run() {
System.out.println("主动创建的第" + num + "个线程");
}
}

  在上面的代码中,通过调用start()方法,就会创建一个新的线程。为了分清start()方法调用和run()方法调用的区别,请看下面一个例子:

 package com.meng.javalanguage.thread.test;

 public class MyThreadTest {
public static void main(String[] args) {
System.out.println("主线程ID:" + Thread.currentThread().getId());
MyThread thread1 = new MyThread("thread1");
thread1.start();
MyThread thread2 = new MyThread("thread2");
thread2.run();
}
} class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
} @Override
public void run() {
System.out.println("name:" + name + " 子线程ID:" + Thread.currentThread().getId());
}
}

  运行结果:

  从输出结果可以得出以下结论:

  1)thread1和thread2的线程ID不同,thread2和主线程ID相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别

  2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行

2、实现Runnable接口

  在Java中创建线程除了继承Thread类之外,还可以通过实现Runnable接口来实现类似的功能。实现Runnable接口必须重写其run方法。

  下面是一个例子:

 package com.meng.javalanguage.thread.test;

 public class MyThreadTest {
public static void main(String[] args) {
System.out.println("主线程ID:" + Thread.currentThread().getId());
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
} class MyRunnable implements Runnable { public MyRunnable() { } @Override
public void run() { System.out.println("子线程ID:" + Thread.currentThread().getId());
}
}

  Runnable的中文意思是“任务”,顾名思义,通过实现Runnable接口,我们定义了一个子任务,然后将子任务交由Thread去执行。注意:这种方式必须将Runnable作为Thread类的参数,然后通过Thread的start方法创建一个新线程来执行该子任务。如果调用Runnable的run方法的话,是不会创建新线程的,这跟普通的方法调用没有任何区别

  事实上,查看Thread类的实现源代码会发现Thread类是实现了Runnable接口的。

  在Java中,这两种方式都可以用来创建线程去执行子任务,具体选择哪一种方式要看自己的需求。直接继承Thread类的话,可能比实现Runnable接口看起来更加简洁,但是由于Java只允许单继承,所以如果自定义类需要继承其它类,则只能选择实现Runnable接口。

转载自《Java并发编程:如何创建线程?》

【转】Java并发编程:如何创建线程?的更多相关文章

  1. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  2. 【Java并发编程六】线程池

    一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...

  3. Java并发编程扩展(线程通信、线程池)

    之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...

  4. 【java并发编程实战】-----线程基本概念

    学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...

  5. Java并发编程:进程和线程的由来(转)

    Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...

  6. 【Java并发编程一】线程安全和共享对象

    一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...

  7. Java并发编程(01):线程的创建方式,状态周期管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...

  8. JAVA并发编程学习笔记------线程的三种创建方式

    创建线程一般有如下几个方式: 1. 通过继承Thread类来创建一个线程: /** * 步骤1:定义一个继承Thread类的子类 * 步骤2:构造子类的一个对象 * 步骤3:启动线程: * */ pu ...

  9. Java并发编程(02):线程核心机制,基础概念扩展

    本文源码:GitHub·点这里 || GitEE·点这里 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效 ...

  10. Java并发编程(04):线程间通信,等待/通知机制

    本文源码:GitHub·点这里 || GitEE·点这里 一.概念简介 1.线程通信 在操作系统中,线程是个独立的个体,但是在线程执行过程中,如果处理同一个业务逻辑,可能会产生资源争抢,导致并发问题, ...

随机推荐

  1. Linux记录-shell获取hdfs used使用

    #!/bin/bash export JAVA_HOME=/app/jdk/jdk1.8.0_92 export HADOOP_HOME=/app/hadoop export HADOOP_CONF_ ...

  2. Django之组件--auth组件

    目录 Auth模块是什么 auth模块常用方法 扩展默认的auth_user表 1 Django自带的用户认证模块,可以快速的实现登录,注销,修改密码... 2 扩展auth表,需要继承Abstrac ...

  3. java 写一个 map reduce 矩阵相乘的案例

    1.写一个工具类用来生成 map reduce 实验 所需 input 文件 下面两个是原始文件 matrix1.txt 1 2 -2 0 3 3 4 -3 -2 0 2 3 5 3 -1 2 -4 ...

  4. SCTP接口模型

    一.接口模型 (1)SCTP套接字分为:一到一套接字和一到多套接字: (2)一到一套接字对应一个单独的SCTP关联(一个SCTP关联是两个系统之间的一个连接,不过可能由于多宿原因而在每个断点设计不止 ...

  5. Metaprogramming

    Metaprogramming https://en.wikipedia.org/wiki/Metaprogramming 元编程, 是一种编程技术, 制造的计算机程序,具有这种能力, 对待程序为他们 ...

  6. position:fixed 失效

    如果position:fixed 失效,那应该是你设置position的元素的父元素中有设置了transform属性哦 . 把 transform删除或设置为none就可以解决啦. 但是如果trans ...

  7. fail2ban 防爆破,防止CC 攻击

    fail2ban fail2ban监视检测日志文件,根据匹配日志的错误信息(正则式匹配)执行相应的屏蔽动作. 可用来放置爆破 和 CC 攻击. 安装: yum install fail2ban -y ...

  8. Linux top 命令详解

    Top  top 查看资源占用 top -p pid# 查看某个进程PID 的内存占用: PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 NInice:值 VIRT: ...

  9. 第26月第25天 ubuntu openjdk-8-jdk jretty

    1.ubuntu ============== sudo apt-get install openjdk-8-jdk https://blog.csdn.net/zhaohaiyitian88/art ...

  10. 自定义函数hello,并注册到hive源码中并重新编译

    1 编写自己的udf方法hello package cn.zhangjin.hive.udf; import org.apache.hadoop.hive.ql.exec.Description; i ...