多线程的最基础使用

 

 继承Thread

package com.example.demo.Thread;

public class MyThreadTest1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("我是run方法-----");
        }
    }

    public static void main(String[] args) {
        MyThreadTest1 myThreadTest1=new MyThreadTest1();

//        run方法和start()的区别在于:
//                调用run(),只有主线程一条执行路径
//                调用start(),子线程执行run()方法,多条执行路径,主线程和子线程并行交替执行

        myThreadTest1.start();


        for (int i = 0; i < 2000; i++) {
            System.out.println("我是main函数-----");
        }
    }
}

 

 

 

 

 

实现Runnable接口

public class MyRRunableTest1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 2000; i++) {
            System.out.println("我是run方法-----");
        }

    }


    public static void main(String[] args) {
        //创建runnable接口实现类对象
        MyThreadTest1 myThreadTest1=new MyThreadTest1();

//        第一种写法、创建线程对象开启线程,代理类对象
//        Thread thread = new Thread(myThreadTest1);
//        thread.start();
//          第二种写法
        new Thread(myThreadTest1).start();

        for (int i = 0; i < 2000; i++) {
            System.out.println("我是main函数-----");
        }
    }
}

利用实现Runnable接口做一个一份资源多个代理的举例,发现问题:

 

    一个资源多个线程用,线程不安全,可能导致并发

 

package com.example.demo.Thread;

public class MyRunnableTest2 implements Runnable{

    @Override
    public void run() {
//一份资源多个代理
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"拿到了第"+i+"票");
        }
    }

    public static void main(String[] args) {
        MyRunnableTest2 myRunnableTest2=new MyRunnableTest2();
//        new Thread(myRunnableTest2,"小丽(名称)").start();
         new Thread(myRunnableTest2,"小丽").start();
        new Thread(myRunnableTest2,"小张").start();
        new Thread(myRunnableTest2,"小王").start();

//     一份资源多个代理   发现问题,一个资源多个线程用,线程不安全,可能导致并发
//        运行结果:
//        小丽拿到了第0票 小丽拿到了第1票 小丽拿到了第2票 小丽拿到了第3票  小丽拿到了第4票 小丽拿到了第5票
//        小张拿到了第0票 小张拿到了第1票 小张拿到了第2票 小张拿到了第3票 小张拿到了第4票  小张拿到了第5票
//        小王拿到了第0票 小王拿到了第1票  小王拿到了第2票   小王拿到了第3票  小王拿到了第4票 小王拿到了第5票


    }
}

 

 

 

 

 

小结:

  #  继承Thread类     

      • 子类继承Threa类具备多线程能力
      • 启动线程:子类对象.start()  
      • 不建议使用:避免OOP单继承局限性      

  #  实现Runnabile接口

      •  实现接口Runnable具有多线程能力
      •    启动线程: 传入目标对象+thread对象.start() 例如:new Thread(目标对象).start()  
      •    推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用      

 

龟兔赛跑案例:

 

 

package com.example.demo.Thread;

public class Ract implements Runnable{

    private static String winner; //胜利者


    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            //判断比赛是否结束
            boolean b = gameOver(i);
//            比赛结束,停止程序
            if (b==true){

                break;
            }
            //模拟兔子休息
//            if (Thread.currentThread().getName().equals("兔子")){
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
            System.out.println(Thread.currentThread().getName()+"---跑了"+i+"步");
        }

    }
//判断比赛是否完成
    boolean gameOver(int step){

        if(winner!=null ){//已经有胜利者
           return true;
        }else{
              if (step>=100) {
                 winner= Thread.currentThread().getName();
                  System.out.println("winner is "+ winner);
              }
        }
        return false;

    }
    public static void main(String[] args) {
        Ract ract=new Ract();

        new Thread(ract,"兔子").start();
        new Thread(ract,"乌龟").start();

    }
}

 

    

posted @ 2022-08-16 15:18  掀起你的头盖骨  阅读(18)  评论(0编辑  收藏  举报