Java oop 第13章_多线程
第13章_多线程
一、 多线程相关的概念:
- 程序:由某种编程语言开发可执行某些功能的代码组合,它是静态的概念。
- 进程:当程序被执行时的过程可以理解为讲程序从外存调入内存的过程,会为每一个程序至少开辟一个独立的内存空间,程序在内存中的状态称为一个进程。
- 线程:一个进程至少会有一个独立的内存空间,但线程是依附在进程的内存空间中工作的,因此它没有自己的独立内存空间,多个线程会共用一个进程的内存空间。
- 多线程开发:往往一个进程中可以包含多个线程,多线程开发就是要具体实施一个进程中执行(启动)多个线程。
二、 Java中如何实现多线程开发:
- 通过继承Thread类,并重写Run方法完成多线程开发。
当一个类继承Thread父类就可以通过该类调用start()方法启动线程,创建多个对象就可以启动多个线程,run()方法是在启动线程时由JVM调用执行。
代码参考:com.oop.ch13.ThreadTest
package com.oop.ch13; /**
* 练习通过继承Thread类,并重写Run()方法完成多线程开发。
*
*/
public class ThreadTest {
public static void main(String[] args) {
Person person = new Person();
person.start(); Person person1 = new Person();
person1.start(); Person person2 = new Person();
person2.start(); } } class Person extends Thread { @Override
public void run() {
Integer nums = 1;
while (true) {
if (nums <= 5) {
System.out.println(Thread.currentThread().getName() + "线程第" + nums + "次输出");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
nums++;
} else {
System.out.println("执行完成");
break;
} }
} }
- 通过实现Runnable接口,并实现Run方法完成多线程开发。
因为Java是一个单继承的编程语言,因此为了完成多线程开发,我们可能通常会直接实现Runnable接口,而不是继承Thread父类。
当一个类实现Runnable接口后,在创建Thread对象时可以将实现了Runnable的实现类对象作为参数,从而通过Thread的对象来启动多个线程。
代码参考:com.oop.ch13.RunnableTest
package com.oop.ch13;
/**
* 练习:通过实现Runnable接口,并实现Run方法完成多线程开发。
*
*/
public class RunnableTest {
public static void main(String[] args) {
Animal animal = new Animal(); //将Animal的对象作为参数传给Thread
Thread thread1 = new Thread(animal);
thread1.start(); Thread thread2 = new Thread(animal);
thread2.start(); Thread thread3 = new Thread(animal);
thread3.start();
}
} class Animal implements Runnable{
@Override
public void run() {
Integer nums = 1;
while (true) {
if (nums <= 5) {
System.out.println(Thread.currentThread().getName() + "线程第" + nums + "次输出");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
nums++;
} else {
System.out.println("执行完成");
break;
} } }
}
三、 解决多线程开发中存在的问题:
问题:在进行多线程开发时会存在线程安全的问题(同步问题),多个线程共用一个进程的内存空间,访问的变量、方法都是同一个。
解决方案:使用一个解决同步问题的关键字synchronized,具体使用方式有两种。
方式1:使用synchronized关键字修饰方法,方法就为同步方法;
方式2:使用synchronized关键字修饰一段代码块,编写一段同步代码块。
案例描述:模拟“机票销售系统”,多个窗口会销售同一个航班的票,要保证机票不能出现多个窗口销售同一张机票的情况。
代码参见:
com.oop.ch13.WindowTest
package com.oop.ch13;
/**
* 模拟“机票销售系统”,多个窗口会销售同一个航班的票,要保证机票不能出现多个窗口销售同一张机票的情况。
* 没有进行同步处理。
*
*/
public class WindowTest {
public static void main(String[] args) {
Window window = new Window(); Thread thread1 = new Thread(window);
thread1.start(); Thread thread2 = new Thread(window);
thread2.start(); Thread thread3 = new Thread(window);
thread3.start(); }
} class Window implements Runnable{ @Override
public void run() {
Integer nums = 20;
while(true) {
if (nums >0) {
System.out.println(Thread.currentThread().getName() + "销售了剩余的第" + nums + "张票");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
nums --;
}else {
System.out.println("机票销售完成");
break;
}
}
}
}
com.oop.ch13.WindowSynchronizedTest
package com.oop.ch13; /**
* 模拟“机票销售系统”,多个窗口会销售同一个航班的票,要保证机票不能出现多个窗口销售同一张机票的情况。
*
* 进行同步处理。
*
*/
public class WindowSynchronizedTest {
public static void main(String[] args) {
Windows windows = new Windows(); Thread thread1 = new Thread(windows);
thread1.start(); Thread thread2 = new Thread(windows);
thread2.start(); Thread thread3 = new Thread(windows);
thread3.start(); }
} class Windows implements Runnable { //声明为成员变量,这样多个线程共用的才是同一个变量,否则每个线程都会运行一遍run()方法
Integer nums = 20;
@Override
/*
* 用synchronized关键字修饰一段代码块
* 或用synchronized修饰方法,就是同步方法
* public void synchronized run(){}
*
*/ public void run() {
while (true) {
//同步处理
synchronized (this) {
if (nums > 0) { System.out.println(Thread.currentThread().getName() + "销售了剩余的第" + nums + "张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
nums--; } else {
System.out.println("机票销售完成");
break;
}
}
} }
}
四、 线程的五种状态:
1、 创建(New):
2、 就绪(Runnable):
3、 运行(Running):
4、 阻塞(Blocked):
5、 死亡(Dead):

Java oop 第13章_多线程的更多相关文章
- java oop第11章_反射、BaseDao的进一步改造
引言:从Java5开始,Java中引用了一个新的概念反射,当程序运行时,能动态感知到程序中拥有的所以信息,这个获取信息的过程是采用反射机制来完成. 一. Class类: Class类用 ...
- java oop第07章_集合框架
一. 什么是集合: 在Java中提供了一些可以保存同一数据类型的数据集称为集合,就是规定了一些集合的规范(接口.抽象类.实现类)及方法, 方便我们程序在保存数据时进行增.删.改.查操作,编程更加高效. ...
- java oop第06章_异常处理
一. 异常的概念: 若程序都按我们事先设定的计划运行为正常执行,但通常会出现我们事先预料之外的其他情况,称为程序发生异常, 在java中会对一些可能出现异常的代码进行分类,达到尽量对可能发生的异常进行 ...
- Java oop第05章_多态、接口
一. 为什么需要接口? Java中当一个类继承父类时,最多也只能继承一个父类,扩展性会受到一定的限制,为了弥补这一缺陷,Java又提供了一种新的引用数据类型分类,叫接口. 一个类只能继承一个父类,但可 ...
- java OOP第03章_继承、抽象类和抽象方法
一. 为什么需要继承: 若多个类中都需要一些属性和方法,那么就可以将属性和方法抽取到一个父类中,需要的子类可以通过extends关键字去继承这个父类后拥有相应的属性和方法. 类.数组.方法----引用 ...
- Java OOP——第七章 多线程
1.进程:是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间): Eg:用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器, ...
- java oop第09章_JDBC02(CRUD操作)
第09章_JDBC02(CRUD操作) CRUD(CREATE . RETIVE . UPDATE . DELETE)增删改查. DAO中会提供一些CRUD操作方法,调用者可以通过调用这些方法完成相应 ...
- 04747_Java语言程序设计(一)_第8章_多线程
例8.1应用程序用Thread子类实现多线程. import java.util.Date; public class Example8_1 { static Athread threadA; sta ...
- 深入理解java虚拟机-第13章-线程安全与锁优化
第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施, ...
随机推荐
- 10个艰难的Java面试题与答案
10个最难回答的Java面试题 这是我收集的10个较难回答的 Java 面试题.这些问题主要来自 Java 核心部分 ,不涉及 Java EE 相关问题.这些问题都是容易在各种 Java 面试中被问到 ...
- 破解Pycharm 2019.2
参考:https://www.cnblogs.com/pig66/p/11432446.html 1.下载补丁文件 https://pan.baidu.com/s/112tS3XjAENIHaJ-aS ...
- svn - Subversion 命令行客户端工具
SYNOPSIS 总览 svn command [options] [args] OVERVIEW 概述 Subversion 是一个版本控制系统,允许保存旧版本的文件和目录 (通常是源代码),保存一 ...
- 第九章 Service
2019-09-23 今天距离2020年刚好有一百天,希望在未来的百日里能不负期待 不忘初心,方得始终, 初心易得,始终难守. 一.Service 的概念 Kubernetes Service定义了这 ...
- hbase GC优化
编辑配置文件 编辑 hbase-env.sh export HBASE_OPTS="$HBASE_OPTS -XX:+UseCompressedOops -XX:+UseParNewGC ...
- 【CodeVS】 纯OI题
[1203] 判断浮点数是否相等 [青铜 Bronze] 我们一般认为两个浮点数相等,当且当他们之间的误差不超过1e-8. /* 作者:Wanying 题目:p1203 判断浮点数是否相等 */ /* ...
- lombok 注解简单介绍
一.Lombok 的简单介绍和使用 Lombok是一个可以帮助我们简化 Java 代码编写的工具类,通过采用注解的方式简化了 JavaBean 的编写,使我们写的类更加简洁. 1. 添加 Lombok ...
- JDK1.8之后的新特性和新接口
接口的旧特性: 就特性下接口中只有: 常量(必须赋值) 抽象方法abstract(和final static private三个关键字冲突) interface Inter { //int a ; / ...
- Java之数据库连接池
未使用数据库连接池,需要从底层申请数据库连接来访问数据库,访问结束之后需要把链接丢弃.长此以往浪费时间. 数据库连接池就是用容器来申请访问,容器里有很多连接对象,用户来容器里拿一个连接对象一起访问数据 ...
- 使用springBoot和mybatis整合时出现如下错误:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)解决方案
在pom.xml文件中添加如下: <build> <resources> <resource> & ...