第13章_多线程

一、   多线程相关的概念:

  1.  程序:由某种编程语言开发可执行某些功能的代码组合,它是静态的概念。
  2.   进程:当程序被执行时的过程可以理解为讲程序从外存调入内存的过程,会为每一个程序至少开辟一个独立的内存空间,程序在内存中的状态称为一个进程。
  3.   线程:一个进程至少会有一个独立的内存空间,但线程是依附在进程的内存空间中工作的,因此它没有自己的独立内存空间,多个线程会共用一个进程的内存空间。
  4.   多线程开发:往往一个进程中可以包含多个线程,多线程开发就是要具体实施一个进程中执行(启动)多个线程。

二、   Java中如何实现多线程开发:

  1.   通过继承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;
} }
} }
  1.  通过实现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章_多线程的更多相关文章

  1. java oop第11章_反射、BaseDao的进一步改造

      引言:从Java5开始,Java中引用了一个新的概念反射,当程序运行时,能动态感知到程序中拥有的所以信息,这个获取信息的过程是采用反射机制来完成. 一.       Class类: Class类用 ...

  2. java oop第07章_集合框架

    一. 什么是集合: 在Java中提供了一些可以保存同一数据类型的数据集称为集合,就是规定了一些集合的规范(接口.抽象类.实现类)及方法, 方便我们程序在保存数据时进行增.删.改.查操作,编程更加高效. ...

  3. java oop第06章_异常处理

    一. 异常的概念: 若程序都按我们事先设定的计划运行为正常执行,但通常会出现我们事先预料之外的其他情况,称为程序发生异常, 在java中会对一些可能出现异常的代码进行分类,达到尽量对可能发生的异常进行 ...

  4. Java oop第05章_多态、接口

    一. 为什么需要接口? Java中当一个类继承父类时,最多也只能继承一个父类,扩展性会受到一定的限制,为了弥补这一缺陷,Java又提供了一种新的引用数据类型分类,叫接口. 一个类只能继承一个父类,但可 ...

  5. java OOP第03章_继承、抽象类和抽象方法

    一. 为什么需要继承: 若多个类中都需要一些属性和方法,那么就可以将属性和方法抽取到一个父类中,需要的子类可以通过extends关键字去继承这个父类后拥有相应的属性和方法. 类.数组.方法----引用 ...

  6. Java OOP——第七章 多线程

    1.进程:是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间): Eg:用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器, ...

  7. java oop第09章_JDBC02(CRUD操作)

    第09章_JDBC02(CRUD操作) CRUD(CREATE . RETIVE . UPDATE . DELETE)增删改查. DAO中会提供一些CRUD操作方法,调用者可以通过调用这些方法完成相应 ...

  8. 04747_Java语言程序设计(一)_第8章_多线程

    例8.1应用程序用Thread子类实现多线程. import java.util.Date; public class Example8_1 { static Athread threadA; sta ...

  9. 深入理解java虚拟机-第13章-线程安全与锁优化

    第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施, ...

随机推荐

  1. Python 字符串常用判断函数

    判断字符串常用函数: S代表某字符串 S.isalnum()  所有字符都是数字或字母,为真返回Ture,否则返回False S.isalha()     所有字符都是字母,为真返回Ture,否则返回 ...

  2. quick'n'dirty poc for CVE-2013-1763 SOCK_DIAG bug in kernel 3.3-3.8

    /* * quick'n'dirty poc for CVE-2013-1763 SOCK_DIAG bug in kernel 3.3-3.8 * bug found by Spender * po ...

  3. CF1239

    然后ZUTTER_打的第一场div1以没敢交题 完!美!结!束!!! A 没有发现性质就找规律海星 我们可以算出一列的贡献:\(g[i][0]\)表示上两个不同,\(g[i][1]\)表示上两个相同就 ...

  4. Codeforces New Year and Arbitrary Arrangement

    New Year and Arbitrary Arrangement time limit per test2 seconds You are given three integers k, pa a ...

  5. redis 发布订阅(pub/sub )

  6. C stdarg.h

    参考:https://www.cnblogs.com/bettercoder/p/3488299.html    博主:运动和行动 va_start宏,获取可变参数列表的第一个参数的地址(list是类 ...

  7. linux系统物理cpu信息查询

    1.查看CPU型号          cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c  2.查看物理CPU的个数            ca ...

  8. Codeforces 1163E 高斯消元 + dfs

    题意:给你一个集合,让你构造一个长度尽量长的排列,使得排列中任意相邻两个位置的数XOR后是集合中的数. 思路:我们考虑枚举i, 然后判断集合中所有小于1 << i的数是否可以构成一组异或空 ...

  9. JAVA练习01

    public class b2 { public static void main(String args[]) { int a[] = {9,1,2,3,5,0,7,8,4,6}; int max, ...

  10. day09 python函数 返回值 参数

    day09 python   一.函数     1.函数         函数是对功能的封装         语法:         定义函数:             def 函数名(形参):    ...