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();
}
}