Java oop 第13章_多线程

Wesley13
• 阅读 679

第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章_多线程

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java多线程的3种实现方式
多线程相关的问题1.什么是进程?​正在执行的程序2.什么是线程?​进程的子单位,一个能够完成独立功能的执行路径3.为什么需要开启多线程?当执行某些耗时操作的任务的时候需要开启多线程,防止线程阻塞能够让两个任务看起来像是在同时执行
lucien-ma lucien-ma
3年前
什么是线程?什么是进程?
Java多线程基础进程和线程的概念应用程序是静态的概念,进程和线程是动态概念,有创建就有销毁,存在也是暂时的,不是永久性的。进程与线程的区别在于进程在运行时拥有独立的内存空间(每个进程所占有的内存都是独立的)多个线程是共享内存空间的,但是每个线程的执行时相互独立的,同时线程必须依赖于进程才能执行,单独的线程是无法执行的,由进程来控制多个线程的执行。
Wesley13 Wesley13
3年前
Java并发基础
一、多线程基础知识1.进程和线程进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。线程:进程内部的一个独立执行单元;一个进程可以同时并发的运行多个线程,
Wesley13 Wesley13
3年前
Java线程与多线程
1线程与多线程1.1线程是什么?线程(Thread)是一个对象(Object)。用来干什么?Java线程(也称JVM线程)是Java进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。Java程序采用多线程方式来支持大量的并发请求处理,程序如果在
Wesley13 Wesley13
3年前
Java面试问题——线程全面详解总结
一、多线程是什么?为什么要用多线程?介绍多线程之前要介绍线程,介绍线程则离不开进程。首先进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元;线程:就是进程中的一个独立控制单元,线程在控制着进程的执行。一个进程中至少有一个进程。多线程:一个进程中不只有一
Stella981 Stella981
3年前
20175216 《Java程序设计》第十周学习总结
教材学习内容总结第12章Java多线程机制12.1进程与进程程序是一段静态的代码,进程是程序的一次动态执行过程,这个过程也是进程本身从产生、发展至消亡的过程。线程不是进程,是比进程更小的执行单位。但与进程不同的是,线程的中断和恢复可以更加节省系统的开销。没有进程就没有线程。
可莉 可莉
3年前
20175216 《Java程序设计》第十周学习总结
教材学习内容总结第12章Java多线程机制12.1进程与进程程序是一段静态的代码,进程是程序的一次动态执行过程,这个过程也是进程本身从产生、发展至消亡的过程。线程不是进程,是比进程更小的执行单位。但与进程不同的是,线程的中断和恢复可以更加节省系统的开销。没有进程就没有线程。