一、多线程:

1.概述:

用多线程只有一个目的,那就是更好的利用cpu的资源,提高程序的运行效率,因为所有的多线程代码都可以用单线程来实现。

一、多线程:

多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
并行与并发:
并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。

二、线程安全:

经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果,如不加事务的转账代码:

void transferMoney(User from, User to, float amount){to.setMoney(to.getBalance() + amount);from.setMoney(from.getBalance() - amount);
}

同步:

Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。
如上面的代码简单加入@synchronized关键字。
在保证结果准确的同时,提高性能,才是优秀的程序。
线程安全的优先级高于性能。

2,进程和线程的区别

进程:计算机中特定功能的程序在数据集上的一次运行。
线程:线程是进程的一个单元。
多线程:一个进程中有多个线程在同时运行,如迅雷软件的一次运行就是一个进程,那么在迅雷中可以同时下载多个电影,这就是多线程(每一个下载都是一个线程)
JVM是多线程的,在我们运行JVM的时候后台会运行垃圾回收的线程,来清理没有被引用的对象.
进程:
线程1、线程2、线程3 …

登录一个QQ就是一个进程:
与多个人聊天对话,就是多个线程。

3.并行和并发的区别

–并发: 是 多个程序 抢占 CPU的执行权
–并行: 是 多个CPU,对应多个程序,每个CPU执行一个程序,不用抢
–效率: 并发 > 并行

4.模拟多线程编程方式

–继承Thread:好处是可以使用父类的所有功能,坏处是单继承/强耦合
–实现Runnable接口:好处是解耦合,可以多继承多实现,坏处是??


二、线程的实现:

1.线程实现的第一种方法:

Thread
创建新执行线程有两种方法。
一种方法是将类声明为Thread的子类,该子类应重写Thread类的run方法。
接下来可以分配并启动该子类的实例。
线程启动的时候 使用线程的start方法而不是run!

2.线程实现的第二种方法:

 Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。 常用方法void run()

继承Thread类

–1,概述

线程 是程序中的执行线程。
Java 虚拟机允许应用程序并发地运行多个执行线程。

–2,创建对象

Thread()
分配新的 Thread 对象。
Thread(Runnable target)
分配新的 Thread 对象。
Thread(Runnable target, String name)
分配新的 Thread 对象。
Thread(String name)
分配新的 Thread 对象。

–3,常用方法

static Thread currentThread()
返回对当前正在执行的线程对象的引用。
long getId()
返回该线程的标识符。
String getName()
返回该线程的名称。
void run()
void setName(String name)
改变线程名称,使之与参数 name 相同。
static void sleep(long millis)
void start()
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
void stop()
已过时。

三、线程的创建方式:

1.方式一 继承Thread:

继承Thread类 子类要重写run方法

public class MyThread extends Thread{//给线程定个变量,取个名字private String name;public MyThread(String name){this.name = name;}/* 线程的执行逻辑体 */@Overridepublic void run(){for (int i = 0; i <= 100; i++) {System.out.println(name+"下载了:"+i+"%");}}
}
public class ThreadTest {public static void main(String[] args) {//创建一个线程的对象MyThread mt = new MyThread("极品飞车14");//启动一个线程mt.start();//开启线程//创建一个线程对象MyThread my = new MyThread("GTA5");//启动一个线程my.start();//开启线程//System.out.println("下载结束");}
}

方式二 Runnable接口:

Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。
类必须定义一个称为 run 的无参数方法。

public class ThreadTest {public static void main(String[] args) {//创建线程对象//创建2个实例的线程Thread t = new Thread(new DownLoad("极品飞车14")); //new DownLoad 创建实例Thread t1 = new Thread(new DownLoad("GTA5")); //new DownLoad 创建实例t.start();t1.start();}
}
public class DownLoad implements Runnable {private String name;public DownLoad(String name){this.name=name;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(name+"下载了:"+i+"%");}}
}

线程的生命周期

**
1.新建:线程被new出来
2.准备就绪:线程具有执行的资格,即线程调用了start(),没有执行的权利
3.运行:具有执行的资格和具备执行的权利
4.阻塞:没有执行的资格和执行权利
5.销毁:线程的对象变成垃圾,释放资源。**


并发

互联网的项目中存在大量的并发案例,如卖火车票、电商网站。

–范例:

火车站有100票,4个窗口同时买票

–分析:

4个窗口是4个线程同时在运行,100张票是4个线程的共享资源
采用继承Thread来实现

并发安全性问题:
4个线程同时抢100张票

package demo;
/*** 这个是卖票的窗口,我们创建4个对象就是4个窗口*/
public class SaleTicketThread extends Thread{private String name;/*** 共享的数据 100张票*/static int tickets = 100;public SaleTicketThread(String name){this.name=name;}@Overridepublic void run(){//卖票是死循环while (true){if (tickets > 0){System.out.println(name+"卖出的座位是:"+(tickets--)+"号");}else{break;}try {Thread.sleep(100);//休眠1秒} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(name+"售票结束,已无票");}
}

测试代码

package demo;public class ThreadTest {public static void main(String[] args) {SaleTicketThread t1 = new SaleTicketThread("同程");SaleTicketThread t2 = new SaleTicketThread("飞猪");SaleTicketThread t3 = new SaleTicketThread("高铁管家");SaleTicketThread t4 = new SaleTicketThread("支付宝");t1.start();t2.start();t3.start();t4.start();}
}

线程并发问题的解决方法(synchronized)

synchronized(锁对象)

语法:synchronized(锁对象){//操作共享资源的代码}
package demo;/*** 这个是卖票的窗口,我们创建4个对象就是4个窗口*/
public class SaleTicketThread extends Thread{private String name;/*** 共享的数据 100张票*/static int tickets = 100;//创建一个锁对象,这个对象是多个线程共享的数据static Object obj=new Object();public SaleTicketThread(String name){this.name=name;}@Overridepublic void run(){//卖票是死循环while (true){synchronized (obj){if (tickets > 0){System.out.println(name+"卖出的座位是:"+(tickets--)+"号");}else{break;}}try {Thread.sleep(200);//休眠2秒} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(name+"售票结束,已无票");}
}

测试代码

package demo;public class ThreadTest {public static void main(String[] args) {SaleTicketThread t1 = new SaleTicketThread("同程");SaleTicketThread t2 = new SaleTicketThread("飞猪");SaleTicketThread t3 = new SaleTicketThread("高铁管家");SaleTicketThread t4 = new SaleTicketThread("支付宝");t1.start();t2.start();t3.start();t4.start();}
}

使用Runnable接口解决并发问题

/**

  • Thread.currentThread().getName() :是一个静态方法
  • this.getName():是一个实例方法
  • JAVA的方法分为:类方法和实例方法:
  • 区别是类方法中有static修饰的,为静态方法,是类方法。
  • 无关键字修饰的为实例方法
  • 注意:
  • static关键字一定要是最先声明的,在说明符float或void前。
    */
 package demo2;/*** Thread.currentThread().getName() :是一个静态方法* this.getName():是一个实例方法* JAVA的方法分为:类方法和实例方法:* 区别是类方法中有static修饰的,为静态方法,是类方法。* 无关键字修饰的为实例方法* 注意:*    static关键字一定要是最先声明的,在说明符float或void前。*/
public class SaleTicket implements RunnableRunnable {//多线程共享的数据 100张票int tickets = 100;//创建一个锁对象,这个对象是多个线程共享的数据Object obj=new Object();@Overridepublic void run(){//卖票是死循环//是持续的while (true){synchronized (obj){if (tickets > 0){System.out.println(Thread.currentThread().getName()+ "卖出的座位是:"+(tickets--)+"号");}else{break;}}try {Thread.sleep(200);//休眠2秒} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"售票结束,已无票");}}

测试代码:

package demo2;public class ThreadTest {public static void main(String[] args) {//创建一个卖票的对象SaleTicket st =new SaleTicket();Thread t1 = new Thread(st,"飞猪");Thread t2 = new Thread(st,"同程");Thread t3 = new Thread(st,"携程");Thread t4 = new Thread(st,"管家");t1.start();t2.start();t3.start();t4.start();}
}

synchronized在方法上修饰的特点

如果synchronized放在对象方法上:

package demo2;
public class SaleTicket implements Runnable {//多线程共享的数据 100张票int tickets = 100;//创建一个锁对象,这个对象是多个线程共享的数据Object obj = new Object();@Overridepublic void run() {//卖票是死循环//是持续的while (true) {if (seleTickets()) {break;}try {Thread.sleep(200);//休眠2秒} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+ "售票结束,已无票");}
 /**** @return 如果一个对象方法上有synchronized的话 那么锁的对象就是this*/public synchronized boolean seleTickets() {//  synchronized (obj) {boolean isFinish = false;if (tickets > 0) {System.out.println(Thread.currentThread().getName()+ "卖出的座位是:" + (tickets--) + "号");} else {isFinish = true;}return isFinish;// }}
}

测试代码:

package demo2;public class ThreadTest {public static void main(String[] args) {//创建一个卖票的对象SaleTicket st =new SaleTicket();Thread t1 = new Thread(st,"飞猪");Thread t2 = new Thread(st,"同程");Thread t3 = new Thread(st,"携程");Thread t4 = new Thread(st,"管家");t1.start();t2.start();t3.start();t4.start();}
}

synchronized 如果在类方法上 那么锁对象就是类的类对象


package demo;
/*** 这个是卖票的窗口,我们创建4个对象就是4个窗口*/
public class SaleTicketThread extends Thread{private String name;/*** 共享的数据 100张票*/static int tickets = 100;//创建一个锁对象,这个对象是多个线程共享的数据static Object obj=new Object();public SaleTicketThread(String name){super(name);//把名字给线程this.name=name;}@Overridepublic void run(){//卖票是死循环while (true){if (saleTickets()){break;}try {Thread.sleep(200);//休眠2秒} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(name+"售票结束,已无票");}public static synchronized boolean saleTickets(){boolean isFinish = false;if (tickets > 0){System.out.println(Thread.currentThread().getName()+"卖出的座位是:"+(tickets--)+"号");}else {isFinish = true;}return isFinish;}
}

测试代码:

package demo2;public class ThreadTest {public static void main(String[] args) {//创建一个卖票的对象SaleTicket st =new SaleTicket();Thread t1 = new Thread(st,"飞猪");Thread t2 = new Thread(st,"同程");Thread t3 = new Thread(st,"携程");Thread t4 = new Thread(st,"管家");t1.start();t2.start();t3.start();t4.start();}
}

JAVA基础 多线程相关推荐

  1. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  2. 2020 - [Java基础 +多线程 + 虚拟机] + [计网 + 操作系统] + [MySQL] + [Redis] + [RocketMQ] + [Spring]常见面试题与解析

    前情提要:下面的内容主要由网上的资料和个人的理解整理而成.由于时间仓促可能没有给出相应的链接,并不代表我不尊重他人的劳动成果,后续更新会补上相应的链接.其中内容可能有理解不到位的地方,大家可选择性采纳 ...

  3. Java基础--多线程

    一.程序.进程.线程 1.区别 (1)程序是一段静态的代码,为应用程序执行的蓝本. (2)进程为程序的一次动态执行过程,包括代码的加载.执行以及执行完毕的一个完整过程. (3)线程是进程中的一个执行单 ...

  4. 黑马程序员——java基础---多线程(二)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! -------  线程间的通信:简单来说,就是多个线程在操作同一资源,但操作的动作不同. 试想一下,对于同一个资 ...

  5. java基础------多线程(转)

    24.01_多线程(多线程的引入)(了解) 1.什么是线程 线程是程序执行的一条路径, 一个进程中可以包含多条线程 多线程并发执行可以提高程序的效率, 可以同时完成多项工作 2.多线程的应用场景 红蜘 ...

  6. 10 Java基础 多线程2

    /* 线程间通讯: 其实就是多个线程在操作同一个资源 但是操作的动作不同 */ class Res { Stringname; Stringsex; } class Input implements ...

  7. java基础—多线程

    1.Thread类 package com.wjl.base;public class MyThread extends Thread {/*** 利用继承的特点* 将线程名称传递 * @param ...

  8. 黑马程序员——Java基础---多线程

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 多线程 一.概述 说起多线程,我们就需要首先来谈谈什么叫做进程.所谓进程,就是在计算机上正在进行 ...

  9. Java基础---多线程宝典

    多线程 文章目录 多线程 核心概念 `Process`与`Thread` 线程三种创建方式 继承`Thread`类 使用多线程实现下载网络图片 实现`Runnable`接口 多线程同时操作同一个对象 ...

  10. 黑马程序员JAVA基础-多线程

    ------- android培训.java培训.期待与您交流! ---------- 线程: 线程是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中至少有一个线程 线程的创建 第一种方 ...

最新文章

  1. 七牛云 直播 java_七牛云直播SDK之推流解析
  2. Py之ipython:Python库之ipython的简介、安装、使用方法详细攻略
  3. 最新最全的视觉Transformer教程!论文分析 + 逐行Coding,带你轻松玩转ViT
  4. ipa去除时间锁_【解密了!】影响沸石分子筛转轮去除效率的因素
  5. java gettime_Java Util.getTime方法代码示例
  6. 使用DataTable动态绑定GridView
  7. matlab将x排序 y随之变化,在MATLAB中:XData和YData如何用更改的行数更新?
  8. 计算机硬件基础课设总结,计算机硬件基础课程设计报告.doc
  9. vs code html插件_VS插件CodeRush全新发布v20.1.7|支持HTML
  10. 语音识别之DTW算法的应用(Python)
  11. 弹出窗口背景透明 css,CSS弹出背景半透明窗口
  12. HTML项目源码:医疗药品商城模板
  13. Exchange2010删除指定账户指定主题邮件
  14. windows下cmd下载文件
  15. 解决IDM下载城通网盘,一个网站不允许请求同一个文件两次,即使设置了快捷键也无用的问题
  16. Ubuntu阿里源镜像
  17. 没有基础怎么自学渗透测试工程师?
  18. 计算机系的对联,轻松写对联 微软亚洲研究院推出电脑对联
  19. 如何购买服务器及域名(阿里)
  20. 行深智能亮相乌镇互联网大会,荣获直通乌镇全球互联网大赛一等奖

热门文章

  1. 使用MATLAB进行多元回归分析(自定义函数公式)——nlinfit函数的使用
  2. 内边距撑大盒子的问题
  3. 如何快速制作一个3d虚拟数字人物形象?
  4. 最优装载问题(将一批集装箱装上一艘载重为轮船,其中集装箱i的重量为Wi(0<=i<=n-1) 最优装载问题是指在装载体积不受限制的情况下,求使得集装箱数目最多的装载方案 )
  5. java-银行卡基本信息查询
  6. mysql基础易错总结
  7. phpCMS后台getshell
  8. pc win端桌面级视频播放器 +electron+vue+element
  9. 2012,传说中的世界末日!
  10. 产品上电时电源电压不稳定的影响及解决办法