2021-07-29

本文介绍了Java中实现多线程的两种方式:通过实现Runnable接口和使用匿名内部类。详细阐述了实现Runnable接口的好处,如避免单继承限制和增强程序扩展性。此外,还通过示例代码展示了如何创建和启动线程,并通过卖票案例探讨了线程安全问题,揭示了并发编程中可能出现的资源竞争问题。
摘要由CSDN通过智能技术生成

1.创建多线程程序的第二种方式实现Runnable接口

实现步骤
1.创建一个Runnable接口的实现类
2.在实现类中重写Runnable接口的run方法,设置线程任务
3.创建一个Runnable接口的实现类对象
4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
5.调用Thread类中的start方法,开启新的线程执行run方法
代码:
/*1.创建一个Runnable接口的实现类
2.在实现类中重写Runnable接口的run方法,设置线程任务
*/
public class RunnableImpl implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + “----” + i);
}
}
}

package cn.itcast.day02;
/*
创建多线程程序的第二种方式:实现Runnable接口
java.lang.Runnable
Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run的无参数方法
java.lang.Thread类的构造方法
Thread(Runnable target)分配新的Thread对象
Thread(Runnable target,String name)分配新的Thread对象。
实现步骤
1.创建一个Runnable接口的实现类
2.在实现类中重写Runnable接口的run方法,设置线程任务
3.创建一个Runnable接口的实现类对象
4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
5.调用Thread类中的start方法,开启新的线程执行run方法
*/

public class Demo01Runnable {

public static void main(String[] args) {
    //3.创建一个Runnable接口的实现类对象
    RunnableImpl run = new RunnableImpl();
    //4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
    Thread t = new Thread(run);
    //5.调用Thread类中的start方法,开启新的线程执行run方法
    t.start();

    for (int i = 0; i < 20; i++) {
        System.out.println(Thread.currentThread().getName() + "----" + i);
    }
}

}

2标题Thread和Runnable的区别

实现Runnable接口创建多线程程序的好处
1.避免了单继承的局限性
一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类
实现了Runnable接口,还可以继承其他的类,实现其他的接口
2.增强了程序的扩展性降低了程序的耦合性(解耦)
实现Runnable接口的方式,把设置线程任务和开启线程进行了分离(解耦)
实现类中重写了Run方法:用来设置线程任务
创建Thread对象,调用start方法:用来开启新线程

3标题匿名内部类方式实现线程的创建

/*
匿名内部类方式实现线程的创建
匿名:没有名字
内部类:写在其他类的内部的类

匿名内部类的作用:简化代码
把子类继承父类,重写父类的方法,创建子类对象一步完成;
把实现类实现类接口,重写接口中的方法,创建实现类对象合成一步完成;
匿名内部类的最终产物:子类/实现类对象,而这个类没有名字

格式:
new 父类/接口(){
重复父类/接口中的方法
}
*/

public class Demo01InnerClassThread {
public static void main(String[] args) {
//线程的父类是Thread
//new MyThread().strat();
new Thread() {
//重写Run方法设置线程任务
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + “黑马”);
}
}
}.start();

    //线程的接口Runnable
    //Runnable r = new RunnableImpl();多态
   Runnable r = new Runnable(){
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "程序员");
            }
        }
    };

   new Thread(r).start();


   //简化接口的方式
    new Thread(new Runnable(){
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "程序员2");
            }
        }
    }).start();


}

}

4.线程安全问题的概述

在这里插入图片描述

5线程安全问题的代码实现

package cn.itcast.day02.demo;
/*
卖票案例:
*/

import java.security.PrivateKey;

public class RunnableImpl implements Runnable {
//定义一个多线程共享的票源
private int tacket = 100;

//设置线程任务:卖票
@Override
public void run() {
    //先判断票是否存在
    while (true) {
        if (tacket > 0) {
            //提高安全问题出现的概率,让程序睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //票存在,卖票 tacket --
            System.out.println(Thread.currentThread().getName() + "--->在卖第" + tacket + "张票!");
            tacket --;
        }
    }
}

}

/*
模拟卖票案例
创建3个线程,同时开启,对共享的票进行出售;
*/
public class Demo01Tacket {
public static void main(String[] args) {
//创建Runnable接口的实现对象
RunnableImpl r = new RunnableImpl();
//创建Thread类对象,构造方法中传递Runnable接口的实现类对象
Thread t0 = new Thread®;
Thread t1 = new Thread®;
Thread t2 = new Thread®;
//调用start方法开启多线程
t0.start();
t1.start();
t2.start();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值