zoukankan      html  css  js  c++  java
  • 第六天学习多线程的创建

    多线程_创建多线程

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

    线程创建

    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();
        }
    }
    
    • 可以定义返回值。
    • 可以抛出异常。
  • 相关阅读:
    elasticsearch 不能通过9200端口访问
    elasticsearch 2.0+ 安装 Marvel
    修改es最大返回结果数
    ElasticSearch的Marvel更新license
    python-execjs(调用js)
    爬取豆瓣电影排名的代码以及思路
    docker的安装
    mysql主从同步
    Docker配置yapi接口
    第24课
  • 原文地址:https://www.cnblogs.com/sxblogs/p/12890269.html
Copyright © 2011-2022 走看看