• Java oop 第13章_多线程


    第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):

     

     

     

     

     

     

  • 相关阅读:
    [MongoDB]
    [solr]
    数据结构-二叉树
    vue-学习笔记-Class 与 Style 绑定
    vue-学习笔记-计算属性和侦听器(computed和watch)
    lodash的debounce函数
    vue-学习笔记-模板语法
    vue-学习笔记-Vue 实例
    vue-介绍章节
    工具网站推荐-jsfiddle,一款在线写代码的网站
  • 原文地址:https://www.cnblogs.com/zhangzimuzjq/p/11792634.html
Copyright © 2020-2023  润新知