zoukankan      html  css  js  c++  java
  • 锁和多线程:线程创建的3种方式(一)

     

     

    搞明白 线程 多线程系列

    1.线程创建

    线程创建常见的三种方式:

    • 继承Thread
    • 实现Runnable接口
    • 实现Callable接口

    第三种方式有异步调用效果,类似js中的ajax可以接收返回值,其余两种不能.

    1.1 继承Thread

    class Thread01 extends Thread {
      public Thread01(String name) {
        super(name);
      }
    
      @Override
      public void run() {
        System.out.println(Thread.currentThread().getName() + "执行...");
      }
    }
    
    

    1.2 实现Runnable接口

    class Thread02 implements Runnable {
    
      @Override
      public void run() {
        System.out.println(Thread.currentThread().getName() + "执行...");
      }
    }
    

    1.3 实现Callable接口

    class Thread03 implements Callable<String> {
    
      @Override
      public String call() throws Exception {
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName() + "执行...");
        return "hello";
      }
    }
    

    使用方式

    package thread;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    /**
     * @Author lyf
     * @Date 2018/11/17 0017 13:38
     */
    public class MyThread {
      public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 继承Thread类  
        new Thread01("线程1").start();
        // 实现Runnable接口
        new Thread(new Thread02(), "线程2").start();
        // 实现Callable接口
        FutureTask<String> futureTask = new FutureTask<>(new Thread03());
        futureTask.run();
        while (futureTask.isDone()) { // 判断线程是否运行结束
          System.out.println("结果: " + futureTask.get());// 获取结果
          return;
        }
      }
    }
    

    2.线程安全

    多线程下访问数据会有线程安全问题.比如买火车票,只有10张票20人买,那就要确保不能卖重,不能多卖.看下面例子:

    package thread;
    
    /**
     * @Author lyf
     * @Date 2018/11/17 0017 14:13
     */
    public class Ticket {
      private int num = 10;
    
      public void buy() {
        if (num > 0) {
          try {
            Thread.sleep((long) (Math.random() * 100));
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println("抢到第" + num-- + "张票...");
        } else {
          System.out.println("票已售罄...");
        }
      }
    
      public static void main(String[] args) {
        final Ticket ticket = new Ticket();
        for (int i = 0; i < 200; i++) {
          new Thread(() -> { ticket.buy(); }).start();
        }
      }
    }
    

     


     

     

    多线程操作下,就会出现多卖的情况.如果要解决,可以通过加锁synchronized方式来实现.把上边的代码修改如下:

    public synchronized void buy() {
      ...
    }
    

     


     

    可以保证不存在多卖情况.

     

  • 相关阅读:
    springboot 的国际化路径出现问题
    算法思想_常见四种
    数据结构_6种简单概述_java
    火狐同步和账号的区别
    java_泛型解析
    购书打折最优方案
    团队小组开发NABC分析
    环状二维数组最大子数组求和
    返回一个整数数组中最大子数组的和之测试
    首尾相连的一位数组最大子数组和
  • 原文地址:https://www.cnblogs.com/linyufeng/p/9991807.html
Copyright © 2011-2022 走看看