zoukankan      html  css  js  c++  java
  • 线程生命周期,创建方式以及如何实现同步和通信

    线程的生命周期

    利用继承的方式创建线程并实现同步

     1 package com.vegeta;
     2 
     3 /**
     4  * 继承方式创建线程,实现同步
     5  *
     6  * @author:qxz
     7  * @create 2020-04-02 10:45
     8  */
     9 public class TestExtends {
    10 
    11     public static void main(String[] args) {
    12         Window window1 = new Window();
    13         window1.setName("窗口一");
    14         Window window2 = new Window();
    15         window2.setName("窗口二");
    16         Window window3 = new Window();
    17         window3.setName("窗口三");
    18         window1.start();
    19         window2.start();
    20         window3.start();
    21     }
    22 
    23 }
    24 
    25 class Window extends Thread {
    26     private static int ticket = 100;
    27 
    28     @Override
    29     public void run() {
    30         while (true) {
    31             synchronized (Window.class) {
    32                 if (ticket > 0) {
    33                     try {
    34                         Thread.sleep(100);
    35                     } catch (InterruptedException e) {
    36                         e.printStackTrace();
    37                     }
    38                     System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "号票");
    39                     ticket--;
    40                 } else {
    41                     break;
    42                 }
    43             }
    44         }
    45     }
    46 }

    利用实现Runnable接口创建多线程并实现同步

     1 package com.vegeta;
     2 
     3 /**
     4  * 利用实现Runnable接口方式创建多线程并实现同步
     5  *
     6  * @author:qxz
     7  * @create 2020-04-02 11:14
     8  */
     9 public class TestRunnable {
    10     public static void main(String[] args) {
    11         WindowRunnable windowRunnable = new WindowRunnable();
    12         Thread window1 = new Thread(windowRunnable);
    13         window1.setName("窗口一");
    14         Thread window2 = new Thread(windowRunnable);
    15         window2.setName("窗口二");
    16         Thread window3 = new Thread(windowRunnable);
    17         window3.setName("窗口三");
    18         window1.start();
    19         window2.start();
    20         window3.start();
    21     }
    22 }
    23 
    24 class WindowRunnable implements Runnable{
    25     private int ticket = 100;
    26 
    27     public void run() {
    28         while (true) {
    29             synchronized (this) {
    30                 if (ticket > 0) {
    31                     try {
    32                         Thread.sleep(100);
    33                     } catch (InterruptedException e) {
    34                         e.printStackTrace();
    35                     }
    36                     System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "号票");
    37                     ticket--;
    38                 } else {
    39                     break;
    40                 }
    41             }
    42         }
    43     }
    44 }

    实现Callable接口创建多线程,Callable接口不适合这种场景,它是带返回值的

     1 package com.vegeta;
     2 
     3 import java.util.concurrent.Callable;
     4 import java.util.concurrent.ExecutionException;
     5 import java.util.concurrent.FutureTask;
     6 
     7 /**
     8  * 实现Callable接口能获取返回值
     9  *
    10  * @author:qxz
    11  * @create 2020-04-02 11:32
    12  */
    13 public class TestCallable {
    14     public static void main(String[] args) throws ExecutionException, InterruptedException {
    15         WindowCallable wc = new WindowCallable();
    16         FutureTask<Integer> futureTask1 = new FutureTask(wc);
    17         FutureTask<Integer> futureTask2 = new FutureTask(wc);
    18         FutureTask<Integer> futureTask3 = new FutureTask(wc);
    19         Thread window1 = new Thread(futureTask1);
    20         window1.setName("窗口一");
    21         Thread window2 = new Thread(futureTask2);
    22         window2.setName("窗口二");
    23         Thread window3 = new Thread(futureTask3);
    24         window3.setName("窗口三");
    25         window1.start();
    26         Integer i1 = futureTask1.get();
    27         System.out.println(i1);
    28         window2.start();
    29         Integer i2 = futureTask2.get();
    30         System.out.println(i2);
    31         window3.start();
    32         Integer i3 = futureTask3.get();
    33         System.out.println(i3);
    34 
    35         System.out.println(i1 + i2 + i3);
    36     }
    37 }
    38 
    39 class WindowCallable implements Callable<Integer>{
    40 
    41     public Integer call() throws Exception {
    42        return 1 + 2;
    43     }
    44 }

    利用线程池实现同步

     1 package com.vegeta;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 import java.util.concurrent.ThreadPoolExecutor;
     6 
     7 /**
     8  * 利用线程池 实现同步
     9  * 
    10  * @author:qxz
    11  * @create 2020-04-02 13:29
    12  */
    13 public class TestPool {
    14     public static void main(String[] args) {
    15         ExecutorService executorService = Executors.newFixedThreadPool(10);
    16         ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
    17         WindowPool windowPool = new WindowPool();
    18         executor.execute(windowPool);
    19         executor.execute(windowPool);
    20         executor.execute(windowPool);
    21         executor.shutdown();
    22     }
    23 }
    24 
    25 class WindowPool implements Runnable{
    26     private int ticket = 100;
    27 
    28     public void run() {
    29         while (true) {
    30             synchronized (this) {
    31                 if (ticket > 0) {
    32                     try {
    33                         Thread.sleep(100);
    34                     } catch (InterruptedException e) {
    35                         e.printStackTrace();
    36                     }
    37                     System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "号票");
    38                     ticket--;
    39                 } else {
    40                     break;
    41                 }
    42             }
    43         }
    44     }
    45 }

    线程交互

     1 /**
     2  * 线程通信的例子:使用两个线程打印 1-100。线程1, 线程2 交替打印
     3  *
     4  * 涉及到的三个方法:
     5  * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
     6  * notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
     7  * notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。
     8  *
     9  * 说明:
    10  * 1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
    11  * 2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
    12  *    否则,会出现IllegalMonitorStateException异常
    13  * 3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。
    14  *
    15  * 面试题:sleep() 和 wait()的异同?
    16  * 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
    17  * 2.不同点:1)两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()
    18  *          2)调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
    19  *          3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
    20  *
    21  * @author shkstart
    22  * @create 2019-02-15 下午 4:21
    23  */
    24 public class CommunicationTest {
    25     public static void main(String[] args) {
    26         Number number = new Number();
    27         Thread t1 = new Thread(number);
    28         Thread t2 = new Thread(number);
    29 
    30         t1.setName("线程1");
    31         t2.setName("线程2");
    32 
    33         t1.start();
    34         t2.start();
    35     }
    36 }
    37 
    38 class Number implements Runnable{
    39     private int number = 1;
    40 
    41     public void run() {
    42         while(true){
    43             synchronized (this) {
    44                 this.notify();
    45                 if(number <= 100){
    46                     try {
    47                         Thread.sleep(10);
    48                     } catch (InterruptedException e) {
    49                         e.printStackTrace();
    50                     }
    51                     System.out.println(Thread.currentThread().getName() + ":" + number);
    52                     number++;
    53                     try {
    54                         //使得调用如下wait()方法的线程进入阻塞状态
    55                         this.wait();
    56                     } catch (InterruptedException e) {
    57                         e.printStackTrace();
    58                     }
    59                 }else{
    60                     break;
    61                 }
    62             }
    63         }
    64     }
    65 }
  • 相关阅读:
    麻省理工18年春软件构造课程阅读13“调试”
    麻省理工18年春软件构造课程阅读15“相等”
    麻省理工18年春软件构造课程阅读12“接口与枚举”
    麻省理工18年春软件构造课程阅读11“抽象函数与表示不变量”
    麻省理工18年春软件构造课程阅读10“抽象数据类型”
    麻省理工18年春软件构造课程阅读09“避免调试”
    麻省理工18年春软件构造课程阅读08“可变性与不变性”
    麻省理工18年春软件构造课程阅读07“设计规格说明”
    麻省理工18年春软件构造课程阅读06“规格说明”
    麻省理工18年春软件构造课程阅读05“版本控制”
  • 原文地址:https://www.cnblogs.com/vegeta-xiao/p/12619737.html
Copyright © 2011-2022 走看看