进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间。(只负责空间分配)

线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程。

多线程:一个进程中时可以有多个线程的,这个应用程序也可以称之为多线程程序。

程序启动了多线程,有什么作用呢?

答:1.可以实现多部分程序同时执行,专业术语称之为并发。

2.多线程的使用可以合理使用CPU的资源,如果线程过多会导致降低性能。

3.CPU处理程序时是通过快速切换完成的,在我们看来好像是随机一样。

/***************************************************************
 * Java 多线程学习.通过代码来演示之前和之后的区别.
 *
 * 在之前的代码中,JVM启动后,必然有一个执行路径(线程)从main方法开始的。
 * 一直执行到main方法结束
 * 在这个线程在java中称之为主线程。
 *
 * 当主线程在这个程序中执行时,如果遇到循环而导致在指定为停留时间过长。
 * 无法执行下面的程序
 * 可不可以实现一个主线程负责执行其中的一个循环,由另一个线程负责其他代码执行。
 * 实现多部分代码同时执行。
 * 这就是多线程技术可以解决的问题。
 *
 * 该如何创建线程呢?
 *
 * 通过API中的中文Thread的搜索,查到了Thread类。
 * 通过阅读Thread类中的描述。
 *
 *       创建线程有两种方式:
 * 1.继承Thread类
 *   1.1 定义一个类继承Thread。
 *   1.2 重写run方法。
 *   1.3 创建子类对象,就是创建线程对象。
 *   1.4 调用这个start方法,开启线程并让线程执行,同时还会告诉JVM去调用run方法。
 *       
 *      为什么要这么做?
 *  继承Thread类,因为Thread类描述线程事物,具备线程应该有的功能。
 *  那为什么不只讲创建Thread类的对象呢?
 *  Thread t1= new Thread();
 *  t1.start();//这么做没有错,但是该start调用时
 *  Thread类中的run方法并没有定义我们需要让线程执行的代码。
 *  
 *     创建线程的目的是什么?
 *  是为了建立单独的执行路径,让多部分代码实现同时执行。
 *  也就是说线程创建并执行需要给定的代码(线程的任务)
 *  对于之前所将的主线程,他的任务定义在main函数中。
 *  自定义线程需要执行的任务都定义在run方法中。
 *  Thread类中的run方法内部的任务并不是我们所需要,只要重写这个run方法。
 *  既然Thread类已经定义了线程任务的位置,只要在位置中定义任务代码即可。
 *  所以进行了重写run方法动作。
 *  
 *  多线程执行是,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。
 *  进行方法的压栈和弹栈。
 *  
 *  当执行线程的任务结束了,线程自动在栈内存中释放了。
 *  但是当所有的执行线程都结束了,进程就结束了。
 *  
 *  //获取线程名称
 *  Thread:currentThread()获取当前线程对象。
 *  怎么名称呢?getName()
 *  Thread.current().getName();
 *  
 *  主线程的名称:main
 *  自定义的线程:Thread-1
 ***************************************************************/

引例:

比如这个案例,只有main主线程一个线程执行程序。

class Demo_01
{
private String name;
Demo_01(String name)
{
this.name=name; }
public void show()
{
for(int x=1;x<=20;x++)
{
System.out.println("name="+name+"........"+x);
}
} /*******************************************
* java中该条线程要执行的代码都存在于main函数中,
* 所以java将这个线程称之为主线程
*******************************************/
public static void main(String[] args)
{
Demo_01 d1=new Demo_01("小强");
Demo_01 d2=new Demo_01("旺财");
d1.show();
d2.show();
} }

运行结果:


例二:

采用多线程方式,main主线程来执行小强方法,新开一个线程来执行旺财方法

内存图

.

class Demo_02 extends Thread
{
private String name;
Demo_02(String name)
{
this.name=name; }
public void run()
{
for(int x=0;x<20;x++)
{
System.out.println("name="+name+"........"+x);
}
} /*******************************************
*
* java中该条线程要执行的代码都存在于main函数中,
* 所以java将这个线程称之为主线程
*
*******************************************/
public static void main(String[] args)
{
//创建了两个线程对象。
Demo_02 d1=new Demo_02("小强");
Demo_02 d2=new Demo_02("旺财");
d2.start();//将d2这个线程开启
d1.run();//由主线程负责
/**********************************************
*
* 调用run方法不开启线程,仅是对象调用方法
* 调用start方法开启线程,并让jvm调用run方法在开启的线程中执行。
*
**********************************************/
} }

例子三:

在例子二的功能实现的基础上实现获取执行的线程名。

class Demo_03 extends Thread
{
private String name;
Demo_03(String name)
{
this.name=name; }
public void run()
{
for(int x=0;x<20;x++)
{
System.out.println("name="+name+"..."+Thread.currentThread().getName()+"....."+x);
}
} /*******************************************
*
* java中该条线程要执行的代码都存在于main函数中,
* 所以java将这个线程称之为主线程
*
*******************************************/
public static void main(String[] args)
{
//创建了两个线程对象。
Demo_03 d1=new Demo_03("小强");
Demo_03 d2=new Demo_03("旺财");
d2.start();//将d2这个线程开启
d1.run();//由主线程负责
/**********************************************
*
* 调用run方法不开启线程,仅是对象调用方法
* 调用start方法开启线程,并让jvm调用run方法在开启的线程中执行。
*
**********************************************/
} }

程序截图:

例子四:

两种方法原理比较图

/*
* 创建线程的第二种方式:实现Runnable接口。
* 1.定义类实现Runnable接口,避免了基础Thread类的单继承局限性。
* 2.覆盖接口中的run方法,将线程任务代码定义到run方法中。
* 3.创建Thread类的对象,只有创建Thread类的对象才可以创建线程。
* 4.将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
* 因为线程已被封装到Runnable接口的run方法中,而这个run方法所属于Runnable接口的子类对象。
* 所以讲这个子类对象作为参数传递给Thread的构造函数,这样,线程对象创建时就可以明确要运行的线程的任务。
* 5.调用Thread类的start方法开启线程。
*
* 第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。
* 实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。
* 继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,又有线程任务。
* 实现Runnable接口:将线程任务单独分离出来封装成对象,类型就是runnable接口类型。
* runnable接口对线程对象和线程任务进行解耦
*
* 通过源码的形式讲解了一下将runnable接口的子类对象作为参数传递给Thread构造函数的原因。
* class Thread{
*
* private Runnable target;
*
* Thread(Runnable target)
* {
* this.target=target;
* }
*
* public void run()
* {
* if(target!=null){
* target.run();
* }
* }
*
* public void start()
* {
*
* run();
* }
* }
*
* */
class Demo_04 implements Runnable
{
private String name;
Demo_04(String name)
{
this.name=name; }
//覆盖了接口Runnable中的run方法
public void run()
{
for(int x=1;x<=20;x++)
{ System.out.println("name="+name+"..."+Thread.currentThread().getName()+"....."+x); } } public static void main(String[] args) { //创建Runnable子类的对象。注意它并不是线程对象
Demo_04 d=new Demo_04("Demo"); //创建Thread类的对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
Thread t1=new Thread(d);
Thread t2=new Thread(d); //将线程启动
t1.start();
t2.start();
System.out.println(Thread.currentThread().getName()+"----------------->"); } }

程序运行截图:

例子五:多线程的应用案例——售票系统

/*
* 案例:售票的例子。
*
* 售票的动作需要同时执行,所以使用多线程技术。
*/
public class Demo_05 implements Runnable {
// 描述票的数量
private int tickets = 100; // 售票的动作,这个动作需要被多线程执行,那就是线程任务代码。需要定义run方法中
// 线程任务中通常都有循环结构。
public void run() {
while (true) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName()+ "........." + tickets--);
}
else
break;
} } public static void main(String[] args) {
// 1.创建Runnable接口的子类对象
Demo_05 t = new Demo_05(); // 2.创建四个线程对象,并将Runnable接口的子类对象作为参数传递给Thread的构造函数。
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
// 3.开启四个线程
t1.start();
t2.start();
t3.start();
t4.start(); }
}

程序运行截图:

Java多线程学习笔记的更多相关文章

  1. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  2. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  3. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

  4. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  5. java 多线程学习笔记

    这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...

  6. Java 多线程学习笔记:生产者消费者问题

    前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...

  7. java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...

  8. Java多线程学习笔记(一)

    一 概述 一个进程只有一个至少会运行一个线程,Java中同样存在这样,在调用main方法的时候,线程又JVM所创建. package link.summer7c.test; public class ...

  9. java多线程学习笔记(四)

    上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...

随机推荐

  1. #1094 : Lost in the City

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi gets lost in the city. He does not know where he is ...

  2. ecshop二次开发 购物车添加备注信息

  3. dereverberation

    Typical Approach to Dereverberation DOAs Estimating the directions of arrival of a direct source sig ...

  4. 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

    [题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...

  5. 一种Flash页游前端3D转2D显示技术——PV2D, 颠覆传统吧!

    stage3D很强大,但是客户端硬件加速支持有限. 出来的图形锯齿严重,看上去和果冻一样. Stage3d不兼容2d模式. 总的来说,3D很美好,现实很残酷.但是3D有无可比拟的优势:那就是节省90% ...

  6. JavaWeb表单数据的获取方式

    表单页面 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8&q ...

  7. ng2048源码阅读

    ng2048源码阅读 Tutorial: http://www.ng-newsletter.com/posts/building-2048-in-angularjs.html Github: http ...

  8. canvas绘图、WebGL、SVG

    目录 一.Canvas 1.1.创建canvas元素 1.2.画线 1.3.绘制矩形 1.4.绘制圆弧 1.5.绘制图像 1.6.绘制文字 1.7.随机颜色与简单动画 二.WebGL 2.1.HTML ...

  9. iOS 真机调试不能连接网络的排错过程

    开发环境: macOS 10.12.1 Xcode 8.1 Qt 5.8 gSOAP 2.8 iPhone 6S+iOS 10.1.1   问题: 使用 Qt Quick 写了一个跨平台的应用,在Wi ...

  10. LINQ系列:Linq to Object相等操作符

    相等操作符通过比较两个序列来检查它们相应的元素是否相同.如果两个序列有相同的元素,并且对应元素的值相同,则认为这两个序列是相等的. SequenceEqual操作符判定两个集合是否相等.判定是通过并行 ...