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

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/zhangzimuzjq/p/11792634.html