1.线程和进程

1.1 进程

进程是操作系统的概念,我们运行的一个TIM.exe就是一个进程。



进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体

1.2 线程

线程是依附于进程而存在的,每一个线程必须有父进程;

线程拥有自己的堆栈、程序计数器和局部变量,线程和其他的线程共享进程的系统资源;

进程不能共享内存,而线程之间可以轻松地共享内存

2.多线程的意义

2.1 发挥多核处理器最大性能

如一个四核处理器去运行单线程任务,一个核心只能运行一个线程,那么三个核心的性能就会被浪费。再如服务器32核CPU运行一个单线程任务,31个核心在“偷懒”,大大地浪费了服务器性能;

比如博主的电脑CPU是i7 6700HQ,四核八线程。该CPU用到了超线程技术。简单地说,一个单核心的处理器,去模拟出双核心的环境,但这并非能够把处理器的效能提升双倍,原因在于实体的核心始终只有一个,而效能有约百分之二十至三十增长。

我们可以理解成阉割版八核处理器,难道买不起八核,还买不起八线程处理器吗?

2.2 发挥单核处理器最大性能

如果进程是单线程的,它在等待某个I/O操作完成,此时处理器处于空闲状态;如果进程是多线程的,一个线程在等待某个I/O操作完成的时候,另外一个线程可以执行。

单核处理器执行多线程的情况

1.单核CPU同一时间,CPU只能处理1个线程,只有1个线程在执行

2.多线程同时执行:是CPU快速的在多个线程之间的切换

3.CPU调度线程的时间足够快,使我们产生错觉,多线程“同时”执行

4.如果线程数非常多,CPU会在n个线程之间切换,消耗大量的CPU资源,每个线程被调度的次数会降低,线程的执行效率降低

3.创建线程

3.1 继承Thread

继承Thread,重写run方法。

public class MyThread00 extends Thread{
public void run()
{
for (int i = 0; i < 50; i++)
{
System.out.println(Thread.currentThread().getName() + "在运行!");
}
} public static void main(String[] args)
{
MyThread00 mt0 = new MyThread00();
//启动线程
mt0.start(); //main线程
for (int i = 0; i < 50; i++)
{
System.out.println(Thread.currentThread().getName() + "在运行!");
}
}
}

start方法:

调用start方法Java虚拟机会启动run方法;

一个线程不能多次调用start方法;

死去的线程不能被重启;

执行结果如下:

main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
......

线程交替执行,不会按照固定顺序执行,每次执行的结果都不一致。

3.2 实现Runnable

实现Runnable接口,重写run方法;有利于代码解耦。

public class MyThread01 implements Runnable
{
public void run()
{
for (int i = 0; i < 50; i++)
{
System.out.println(Thread.currentThread().getName() + "在运行!");
}
} public static void main(String[] args)
{
MyThread01 mt0 = new MyThread01();
Thread t = new Thread(mt0);
//启动线程
t.start();
//main线程
for (int i = 0; i < 50; i++)
{
System.out.println(Thread.currentThread().getName() + "在运行!");
}
}
}

执行结果类似于3.1

3.3 实现Callable

实现Callable创建线程,重写call方法,该方法可以返回值和抛出异常

public class MyThread02 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("计算处理中...");
Thread.sleep(3000);
return 1;
} public static void main(String[] args) {
//构建任务
MyThread02 t = new MyThread02();
//执行Callable方式,需要FutureTask实现类的支持,用于接收运算结果
FutureTask<Integer> task = new FutureTask<Integer>(t);
//启动线程
new Thread(task).start();
//获取结果
try {
Integer integer = task.get(5000,TimeUnit.MILLISECONDS);
System.out.println("线程执行结果:"+integer);
} catch (Exception e) {
e.printStackTrace();
}
}
}

执行结果如下

计算处理中...
线程执行结果:1

我们获取到了call方法的返回值,继承Thread和实现Runnable方式创建线程无法获得返回值

Java多线程(一):线程与进程的更多相关文章

  1. Java多线程:线程与进程

    实际上,线程和进程的区别,在学OS时必然是学习过的,所缺的不过是一些总结. 1. 进程 2. 线程 3. 进程与线程 4. 多进程与多线程对比 5. Java多进程与多线程 5.1. Java多进程 ...

  2. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  3. JAVA多线程之线程间的通信方式

    (转发) 收藏 记 周日,北京的天阳光明媚,9月,北京的秋格外肃穆透彻,望望窗外的湛蓝的天,心似透过栏杆,沐浴在这透亮清澈的蓝天里,那朵朵白云如同一朵棉絮,心意畅想....思绪外扬, 鱼和熊掌不可兼得 ...

  4. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  5. 处理java多线程时线程安全问题 - ThreadLocal和Synchronized

    多线程在自动化测试中用的不多,也就是说我们用单线程可以完成大部分的自动化测试脚本. 主要有两个原因,首先是因为自动化测试首要考虑的是脚本的稳定性,所以一般会牺牲效率以保证脚本稳定,其次是由于局限于我们 ...

  6. java多线程之 ---- 线程死锁

    java多线程之线程死锁 产生死锁的主要原因: 由于系统资源不足. 进程执行推进的顺序不合适. 资源分配不当等. 假设系统资源充足.进程的资源请求都可以得到满足,死锁出现的可能性就非常低.否则就会因争 ...

  7. Java多线程| 01 | 线程概述

    Java多线程| 01 | 线程概述 线程相关概念 进程与线程 进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位.可以把进程简单的理解 ...

  8. Java多线程之线程其他类

    Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...

  9. Java多线程之线程的通信

    Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...

  10. Java多线程之线程的同步

    Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...

随机推荐

  1. JS 小脚本汇聚

    根据文件length展示文件大小 if (bytes === 0) return '0 B'; var k = 1024, sizes = ['B', 'KB', 'MB', 'GB', 'TB', ...

  2. 最初学习mysql的一些操作留存

    一:数据库的初始话操作 mysql -u root -p    //数据库的登陆 show databases:    //展现数据哭中存储的所有文件 use 数据库名:        //进入当前要 ...

  3. jwt token and shiro

    openapi可以完全开放访问,也可以使用jwt token进行简单的认证,还可以使用shiro支持更细致的权限管理. handler.yml配置了security和shiro两个handler: s ...

  4. Docker小记

    1.Docker的安装 这里给一个比较通用的教程 Ubuntu 14.04 16.04 (使用apt-get进行安装) # step : 安装必要的一些系统工具 sudo apt-get update ...

  5. oracle存储过程中进行分页

    create or replace procedure APP_BUSSINESS_CARD_LIST(p_in_str in varchar2,p_out_str out varchar2) is ...

  6. How to install WireShark on Linux

    https://linuxtechlab.com/install-wireshark-linux-centosubuntu/

  7. C#计算两个时间年份月份天数(根据生日计算年龄)差,求时间间隔

    C#计算两个时间年份月份差 DateTime dt1 = Convert.ToDateTime("2008-8-8"); DateTime dt2 = System.DateTim ...

  8. spring boot 全局异常处理及自定义异常类

    全局异常处理: 在处理controller层抛出的自定义异常时,可以实现@ControllerAdvice注解捕获,配合@ExceptionHandler来增强所有的@requestMapping方法 ...

  9. java 8 中文API

    java 8 中文API 转 https://blog.csdn.net/gao_zhennan/article/details/72871202 java 1.6 帮助文档 中文链接:http:// ...

  10. 使用IEDriverServer.exe驱动IE,实现自动化测试

    1. 下载IEDriverServer: https://www.nuget.org/packages?q=IEDriver 2. 解压缩得到IEDriverServer.exe和IEDriverSe ...