第六天学习多线程的创建

多线程_创建多线程

  • 进程:一个程序执行起来就是一个进程,一个进程可包含多个线程。

线程创建

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口

Thread类(Thread类也始先了runnable接口)

  1. 继承Thread类。
  2. 重写run()方法。
  3. 调用start()方法开启线程。
public class ThreadTest extends Thread{
    //重写run方法
    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 220; i++) {
            System.out.println("RUN"+i);
        }
    }

    public static void main(String[] args) {
        ThreadTest t1 = new ThreadTest();  //new一个ThreadTest
        ThreadTest t2 = new ThreadTest();
        ThreadTest t3 = new ThreadTest();
         //调用start()。(调用run()方法就不按照多线程执行了)
        t1.start(); 
        t2.start();
        t3.start();//三个线程同时执行run()方法内的代码。
        for (int i = 0; i < 220; i++) {
            System.out.println("main"+i);
        }
    }
}

实现Runnable接口(推荐,java单继承多实现)

  1. 定义一个类,实现Runnable接口。
  2. 实现run()方法。
  3. new一个Runnable接口的实现类的对象。
  4. new一个Thread类,将Runnable实现类实例传入形参。
  5. Thread实现类调用start()方法。
public class ThreadTest implements Runnable{
    //实现Runnable接口的run方法
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("run:"+i);
        }
    }
    public static void main(String[] args) {
        //实例化接口实现类
        ThreadTest threadTest = new ThreadTest();
        //实例化RThread类(线程代理)
        Thread thread1 = new Thread(threadTest,name);
        Thread thread2 = new Thread(threadTest,name);
        //启动线程
        thread1.start();
        thread2.start();
    }
}

抢票小demo

public class ThreadTest implements Runnable {
    private int P = 20;
    @Override
    public void run() {

        while (true){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (P<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+P--+"张票子");
        }
    }
    public static void main(String[] args) {
        ThreadTest t = new ThreadTest();
        new Thread(t,"老师").start();
        new Thread(t,"学生").start();
        new Thread(t,"黄牛").start();

    }
}
输出:
        黄牛拿到了第19张票子
        老师拿到了第18张票子
        学生拿到了第20张票子
        学生拿到了第17张票子
        老师拿到了第16张票子
        黄牛拿到了第15张票子
        学生拿到了第13张票子
        老师拿到了第14张票子
        黄牛拿到了第12张票子
        学生拿到了第11张票子
        黄牛拿到了第10张票子
        老师拿到了第9张票子
        黄牛拿到了第8张票子//线程不安全
        学生拿到了第8张票子//线程不安全
        老师拿到了第8张票子//线程不安全
        黄牛拿到了第7张票子
        学生拿到了第6张票子
        老师拿到了第5张票子
        学生拿到了第4张票子
        黄牛拿到了第3张票子
        老师拿到了第4张票子
        老师拿到了第2张票子//线程不安全
        学生拿到了第1张票子
        黄牛拿到了第2张票子//线程不安全
  • Thread类的currentThread()方法可拿到线程的名字等信息。
  • Thread.sleep(200)可以让线程延迟启动。
  • 线程不安全!数据被重复使用了!

龟兔赛跑小demo

public class ThreadTest implements Runnable {
    private static String win;  //胜者,static只执行一次
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) { //跑100步
            if (Thread.currentThread().getName().equals("兔子") && i%10==0){
                try {
                    Thread.sleep(1); //兔子每10米睡一觉
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            boolean b = gameOver(i);
            if (b){ //判断比赛是否结束
               break;
            }else { //记录步数
                System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
            }
        }
    }
    //判断比赛是否结束的方法
    public boolean gameOver(int i){
        if (win!=null){ //产生胜利者
            return true;
        }else if (i==100){ //先到达100的
            win = Thread.currentThread().getName(); //赋值给win
            System.out.println(Thread.currentThread().getName()+"win");
            return true;
        }
        return false;  //还没分出胜负
    }
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        new Thread(threadTest,"乌龟").start();
        new Thread(threadTest,"兔子").start();
    }
}

实现Callable接口

  1. 重写Callable接口(带泛型)。
  2. 重写call方法(有返回值,和泛型相同)。
  3. new一个Callable方法的实现类。
  4. 创建执行任务。
  5. 提交执行。
  6. 获取结果。
  7. 关闭服务。
import java.util.concurrent.*;

public class ThreadTest implements Callable<String> {

    String s;

    //重写call方法
    @Override
    public String call(){
        
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"的i等于:"+i);
            s=Thread.currentThread().getName();
        }
        return s;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //new Callable 接口的实现类
        ThreadTest t1 = new ThreadTest();
        ThreadTest t2 = new ThreadTest();
        ThreadTest t3 = new ThreadTest();
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        //submit提交执行
        Future<String> submit1 = executorService.submit(t1);
        Future<String> submit2 = executorService.submit(t2);
        Future<String> submit3 = executorService.submit(t3);

        //获取结果
        String aBoolean1 = submit1.get();
        String aBoolean2 = submit2.get();
        String aBoolean3 = submit3.get();
        System.out.println(aBoolean1);
        System.out.println(aBoolean2);
        System.out.println(aBoolean3);

        //关闭服务
        executorService.shutdown();
    }
}
  • 可以定义返回值。
  • 可以抛出异常。
posted @ 2020-05-14 17:45  yukinon  阅读(130)  评论(0编辑  收藏  举报