好久没有更博客了,最近一直在忙工作的事情。现在终于空下来了,这2天会抓紧时间整理多线程和socket,把JavaSE结束掉。



关于多线程,首先会涉及到哪些东西呢?首先要了解线程,为什么要使用线程,线程有什么优势,线程和进程有什么区别呢?了解过大致的线程内容后,就应该编码来实现Java的多线程了。首先2种方式来创建线程类,然后调用对应的API来控制线程。然后还剩下一个最大的也是最重要的一块知识,就是线程同步。前面那些了解线程的生命周期就可以,实际编码中并不会多次写到那些编码,但是线程的同步经常要用到。同步代码块,同步方法,同步锁等等还是很重要的。最后就是一个线程池的问题了,这个了解下就好,在后面框架中有好多缓存技术使用了池技术的,我们也不需要编码了。





  • 线程和进程

实际开发中,特别是j2ee中,基本没有一个项目说是单线程的,都是多线程的。比如服务器处理多个请求。

  • 什么是进程?

几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,那么运行的这个程序就叫一个进程。进程的调度由OS负责(有的系统为独占式(Windows),有的系统为共享式(Unix),根据重要性,进程有优先级)。由OS 将时间分为若干个时间片。JAVA 在语言级支持多线程。分配时间的仍然是OS。

  • 什么是线程?

当一个程序运行时,内部可能包含了多个顺序执行流,那么这每一个顺序执行流就叫一个线程。

  • 关于他们2个之间的关系:

一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少要包含一个线程。

线程是一个操作系统创建并维护的一个资源,对操作系统来说JVM就是一个进程。

对于单个CPU系统来说,某一个时刻只可能由一个线程在运行。一个Thread对象就表示一个线程。

进程是独立的数据空间,线程是共享的数据空间。线程对象存在于虚拟机进程空间的一块连续的地址空间(静态的)。

  • 关于线程注意:

1.线程是动态的,与线程对象是两回事.

   2.线程对象与其他对象不同的是线程对象能够到底层去申请管理一个线程资源。

   3.只有对线程对象调用start()方法才是到底层去申请管理一个线程资源。

   4.任务并发执行是一个宏观概念,微观上是串行的。

   5.只有等到所有的线程全部结束之后,进程才退出。进行多线程编程时不要忘记了Java程序运行时默认的主线程,main方法的方法体就是主线程的线程执行体。

  • 在这里要注意2个概念上的区别:并行和并发。

并行指的是在同一时刻,有多条指令在多个处理器上同时执行。

并发指的是在同一时刻,只能有一条指令执行。但是多个指令被快速轮换执行,使得在宏观上有多个进程同时执行。也就是说只是看起来是同时执行的,其实具体实际执行的还是一条而已。

  • 多线程的优势:

1,进程间不能共享内存,但是线程之间共享内存非常容易。

2,系统创建进程需要为进程重新分配系统资源,但创建线程则代价小得多,使用多线程实现多任务并发比多进程的效率高。

3,Java语言内置多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化了Java的多线程编程

  • 线程的创建和启动

一共有2种方式:1,继承Thread类  2,实现Runnable接口。代码如下:

/**
*
* @version 1L
* @author LinkinPark
* @since 2015-2-3
* @motto 梦似烟花心似水,同学少年不言情
* @desc ^ 继承Thread,重写run方法。
*/
public class MyThread extends Thread
{
private int i = 0; public void run()
{
for (; i < 10; i++)
{
//输出中i不连续,说明这种方式不能共享一份系统资源
System.out.println(this.getName() + " " + i);
}
} public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
//输出了主线程
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20)
{
//这里开始抢占输出,注意的是i不连续
new MyThread().start();
new MyThread().start();
}
}
}
}
public class MyThread1 implements Runnable
{
private int i = 0; @Override
public void run()
{
for (; i < 100; i++)
{
//输出中i连续,表明这种方式会共享同一份系统资源
//这里没有Thread,所以只能通过这种方式:先返回当前正在执行的线程对象,然后在获得名字
System.out.println(Thread.currentThread().getName() + " " + i);
}
} public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
//输出主线程
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20)
{
MyThread1 myThread1 = new MyThread1();
//这里开始抢占输出,注意的是i连续
new Thread(myThread1, "林肯的第一个线程").start();
new Thread(myThread1, "林肯的第二个线程").start();
}
}
} }
  • 关于这2种方式创建线程的对比:

首先有必要看一下Thread类的run方法的源码。代码如下:

public void run() {
if (target != null) {
target.run();
}
}

这里有一个target,如何理解这个target呢?run方法又叫线程执行体,我们可以这样子来理解,线程呢就是一段程序流,这段程序流要操作一个对象,那么操作的这个对象就是这个target,值得注意的一点是Java语言的Thread必须使用Runnable对象里面的run方法。





言归正传,这2种实现方式的区别如下:

1,实现Runnable接口,还可以继承其他的类。Java是单继承呀,要是直接去继承Thread类的话就不能再继承别的类了

2,实现Runnable接口,多个线程可以共享同一个target对象,所以非常适合多个相同的线程来处理同一份资源

3,实现Runnable接口,编码稍微有点多。访问当前线程只能使用Thread.currentThread(),要是继承Thread类的话直接使用this就可以获得当前的线程。

Java多线程之线程的创建的更多相关文章

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

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

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

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

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

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

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

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

  5. Java多线程父子线程关系 多线程中篇(六)

    有的时候对于Java多线程,我们会听到“父线程.子线程”的概念. 严格的说,Java中不存在实质上的父子关系 没有方法可以获取一个线程的父线程,也没有方法可以获取一个线程所有的子线程 子线程的消亡与父 ...

  6. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

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

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

  8. Java多线程之线程的生命周期

    Java多线程之线程的生命周期 一.前言 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(R ...

  9. Java多线程之线程的启动

    Java多线程之线程的启动 一.前言 启动线程的方法有如下两种. 利用Thread 类的子类的实例启动线程 利用Runnable 接口的实现类的实例启动线程 最后再介绍下java.util.concu ...

随机推荐

  1. 【转】Tableau 9.3.8 desktop for Mac 中文破解

    tableau破解版本下载地址 安装步骤: 1. 编辑hosts 文件 在终端输入:sudo nano /etc/hosts 添加如下内容: 127.0.0.1 licensing.tableauso ...

  2. Android Studio C/C++开发环境配置

    Android Studio C/C++开发环境配置  我的开发环境 : Win 10 + android studio 1.5   一, 安装NDK 开发环境: 1.  Settings -> ...

  3. sqlite ef6 踩坑

    调试的时候配置写如下,这样写是没有问题的但是在实际环境中有问题,因为EF路径找不到.会提示错误:The underlying provider failed on open <connectio ...

  4. SLAVE为什么一直不动了

    导读 遇到SLAVE延迟很大,binlog apply position一直不动的情况如何排查? 问题描述 收到SLAVE延迟时间一直很大的报警,于是检查一下SLAVE状态(无关状态我给隐去了):   ...

  5. 【读书笔记】【深入理解ES6】#4-扩展对象的功能性

    对象类别 ES6规范清晰定义了每一个类别的对象. 普通(Ordinary)对象 具有JS对象所有的默认内部行为 特异(Exotic)对象 具有某些与默认行为不符的内部行为 标准(Standard)对象 ...

  6. ionic serve 突然报错 node-sass

    正常打开项目,并开启浏览器测试模式: 执行命令: ionic serve:  结果报错: 解决方法: 你可以按照 里面的提示: 直接执行命令: npm rebuild node-sass 然后再重新执 ...

  7. 常见查找算法之php, js,python版

    常用算法 >>>1. 顺序查找, 也叫线性查找, 它从第一个记录开始, 挨个进行对比, 是最基本的查找技术 javaScript 版顺序查找算法: // 顺序查找(线性查找) 只做找 ...

  8. “玲珑杯”ACM比赛 Round #13 题解&源码

    A 题目链接:http://www.ifrog.cc/acm/problem/1111 分析:容易发现本题就是排序不等式, 将A数组与B数组分别排序之后, 答案即N∑i=1Ai×Bi 此题有坑,反正据 ...

  9. hihoCoder #1043 : 完全背包(板子题)

    #1043 : 完全背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的 ...

  10. c语言基础学习04

    =============================================================================涉及到的知识点有:程序的三种结构.条件分支语句 ...