java基础-多线程(2)

92 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天

线程创建

线程创建三种方法:

1.继承 Thread 类(重点)

  • 自定义线程类继承Thread
  • 重写run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程
 public class TestTread1 extends  Thread {
 ​
     @Override
     public void run() {
         //run方法线程体
         for (int i = 0; i < 20; i++) {
             System.out.println("我在看代码。。。");
         }
     }
 ​
     //main线程,主线程
     public static void main(String[] args) {
          //创建一个线程对象
         TestTread1 testTread1 = new TestTread1();
         //调用start方法开启线程
         testTread1.start();
 ​
 ​
         for (int i = 0; i < 1000; i++) {
             System.out.println("我在学习多代码。。。");
         }
     }
 }
 ​

总结

线程不一定立即执行,CPU安排调度


2.实现Runnable接口 (重点)

推荐使用Runnable对象,因为Java单继承的局限性

  1. 自定义线程类实现Runnable接口
  2. 实现run()方法,编写线程执行体
  3. 创建线程对象,调用start()方法启动对象
 public class Demo3_CreateRunnable implements Runnable {
 ​
     @Override
     public void run() {
         //run方法线程体
         for (int i = 0; i < 20; i++) {
             System.out.println("我在看代码----" + i);
         }
     }
 ​
     public static void main(String[] args) {
         //创建runnable接口的实现类对象
         Demo3_CreateRunnable testThread = new Demo3_CreateRunnable();
         //创建线程对象,通过线程对象来开启我们的线程,代理
         Thread thread = new Thread(testThread);
         //调用start()开启线程
         thread.start();
 ​
         //new Thread(testThread).start();
         for (int i = 0; i < 200; i++) {
             System.out.println("我在学习多线程----" + i);
         }
     }
 }
 ​

案例举例

火车票:

多个线程同时操作同一个对象 买火车票案例

发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱

 //买火车票的例子
 public class TestThread4 implements  Runnable{
 ​
 ​
     //票数
     private  int tickeNums = 10;
 ​
     @Override
     public void run() {
 ​
         while (true){
             if(tickeNums <= 0){
                 break;
             }
 ​
 ​
             try {
                 Thread.sleep(200);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             System.out.println(Thread.currentThread().getName() + "拿到了第" + tickeNums--+"张票");
         }
 ​
     }
 ​
 ​
     public static void main(String[] args) {
         TestThread4 ticket = new TestThread4();
 ​
         new Thread(ticket,"小明").start();
         new Thread(ticket,"老师").start();
         new Thread(ticket,"黄牛党").start();
 ​
 ​
 ​
     }
 }
 ​

3.实现Callable接口(了解)

  • 实现Callable接口,需要返回值类型

  • 重写call方法,需要抛出异常

  • 创建目标对象

  • 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);

  • 提交执行:Future result1 = ser.submit(11);

  • 获取结果:boolean r1 = result1.get()

  • 关闭服务:ser.shutdownNow();

    好处:

    1.可以定义返回值

    2.可以抛出异常


4.Thread和Runnable对比

继承Thred类:

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

实现Runnable接口:

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

\