锁和多线程:线程创建3种方式

Posted linyufeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锁和多线程:线程创建3种方式相关的知识,希望对你有一定的参考价值。

 

 

搞明白 线程 多线程系列

1.线程创建

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

  1. 继承Thread类

  2. 实现Runnable接口

  3. 实现Callable接口

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

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;
    }
  }
}


class Thread01 extends Thread {
  public Thread01(String name) {
    super(name);
  }

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

class Thread02 implements Runnable {

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

class Thread03 implements Callable<String> {

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

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() {
  ...
}

 

技术分享图片
 

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

 

以上是关于锁和多线程:线程创建3种方式的主要内容,如果未能解决你的问题,请参考以下文章

Java进阶泛型和多线程

多个请求是多线程吗

python中的多线程和多进程编程

并发和多线程--AbstractQueuedSynchronizer基本原理

多线程 Thread 线程同步 synchronized

122 Python程序中的多进程和多线程