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. 预处理、const、static与sizeof-#pragma pack的作用

    1:有如下代码: #include <iostream.h> #pragma pack(1) struct test{ char c; short s1; short s2; int i; ...

  2. 剑指offer35----复制复杂链表

    题目: 请实现一个cloneNode方法,复制一个复杂链表. 在复杂链表中,每个结点除了有一个next指针指向下一个结点之外,还有一个random指向链表中的任意结点或者NULL. 结点的定义如下: ...

  3. Netfilter 之 钩子函数与钩子点关系图

    概述 通过钩子点和优先级的代码追溯,得到如下对应关系图,图中横坐标为钩子点,纵坐标为优先级,每个钩子点上的钩子函数按照优先级排布: 详细分析 5个钩子点如下所示,在这个五个钩子点上的钩子函数按照上面的 ...

  4. Android屏幕横竖屏切换和生命周期管理的详细总结

    一般的我们去切换屏幕方向都是不希望Activity被重新创建,这时就需要对一些属性进行设置,或者使用代码设置.        今天想学一下Android屏幕横竖屏切换,但是网上很多知识不准确或不正确, ...

  5. 【学习笔记】QT常用类及应用

    一.QT基类: QObject 二.QT中常用的库 QT中的类根据功能划分在不同的库中,在用户属性.pro文件中可以看到. 三.Qt基本对话框的使用 常用5类: 通过类名可以直接调用类的静态成员函数. ...

  6. 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下

    笔记 5.高级篇幅之高并发情况下接口限流特技         简介:谷歌guava框架介绍,网关限流使用 1.nginx层限流 2.网关层限流 开始 mysql最大的连接数就是3千多.如果想把应用搞好 ...

  7. [Spark] Spark 3.0 Accelerator Aware Scheduling - GPU

    Ref: Spark3.0 preview预览版尝试GPU调用(本地模式不支持GPU) 预览版本:https://archive.apache.org/dist/spark/spark-3.0.0-p ...

  8. GlusterFS集群

    使用架构: 2台机器安装 GlusterFS 组成一个 Distributed Replicated Volumes集群 192.168.0.92 服务端 192.168.0.93 服务端 192.1 ...

  9. gdb调试caffe工程

    环境:UBUNTU 16.04 CMake caffe 1.0.0-rc3 1.首先编译caffe为debug版本: 在caffe根目录下编辑CMakeFileList.txt,加入如下几行: SET ...

  10. uni-app 封装 http promise请求,仅提供 post,all,spread 方法

    简单封装一下 uni-app 的请求,因为项目中只用 post 请求,所以只封装了 post 和 all 方法. 更新,新增 spread 方法 2019-11-22 10:37:21 global. ...