Java开发——35.多线程_(线程的创建及使用)

简介: 线程创建方式:1.继承Thread类;2.实现Runnable接口。

进程:系统资源分配的单位;

线程:处理器任务调用和执行的单位,线程之间共享进程资源;


今天先学习两种API定义的线程创建方式:1.继承Thread类;2.实现Runnable接口。

image.png


1.方式一:继承Thread类创建线程;



//1.自定义类继承Thread类//2.重写Thread类中的run()方法//2.1要执行的内容写在run()方法内//3.在测试类中创建自定义类实例//4.开启进程start()//4.1一个自定义的实现类只能开启一个线程,只能调用一次start()方法



//1.自定义类继承Thread类classMyThreadextendsThread{
//2.重写Thread类中的run()方法@Overridepublicvoidrun() {
//需要执行的内容:输出0-100之内的偶数for (inti=0; i<100; i++) {
if (i%2==0)
//Thread.currentThread().getName():获取当前线程的名字System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
publicclassDemoThread {
publicstaticvoidmain(String[] args) {
//3.在测试类中创建自定义类实例MyThreadmt=newMyThread();
//4.开启进程start()mt.start();
    }
}


2.方式二:实现Runnable接口创建线程;


//1.自定义类实现Runnable接口//2.实现Runnable接口中的run()方法//2.1要执行的内容写在run()方法内//3.创建自定义类的实例对象//4.创建Thread类对象,并把第三部创建的自定类的实例对象当做参数传给Thread构造器//5.使用Thread类对象,调用start()方法,开启线程


//1.自定义类实现Runnable接口classMyRunnableimplementsRunnable{
//2.实现Runnable接口中的run()方法@Overridepublicvoidrun() {
//需要执行的内容:输出0-100之内的偶数for (inti=0; i<100; i++) {
if (i%2==0){
System.out.println(Thread.currentThread().getName() +":"+i);
            }
        }
    }
}
publicclassDemoRunnable {
publicstaticvoidmain(String[] args) {
//3.创建自定义类的实例对象MyRunnablerunnable=newMyRunnable();
//4.创建Thread类对象,并把第三部创建的自定类的实例对象,当做参数传给Thread构造器Threadthread=newThread(runnable);
//5.使用Thread类对象,调用start()方法,开启线程thread.start();
    }
}


注意事项:

1.为什么使用thread.start()开始了线程,却执行了实现Runnable接口中实现的run()方法?

image.png


2.Thread类底层,也实现了Runnable接口;

image.png


继承Thread类和实现Runnable接口的区别:

在两种创建线程的方法中优先选择:实现Runnable接口

1.实现Runnable接口,避免了Java中类只能单继承的局限性;

2.实现Runnable接口,能实现资源共享;继承Thread类则需要声明为static才能实现资源共享。

(实现Runnable接口,它的实现类只用创建一次,只要创建多个Thread类,就能实现创建多个线程,天然的资源共享;继承Thread类,每创建一个线程,就需要创建一个继承自Thread类的子类,如果不把资源声明为static,则每创建一个继承自Thread类的子类,就会有一个新的资源...)


使用多线程实现买100张票:

继承Thread类(存在线程不安全的问题,会出现重票的现象,在后续线程同步的时候会讲。)

现Runnable接口也是一样的效果,这里不在演示。

publicclassPraSaleTicket {
publicstaticvoidmain(String[] args) {
Salesale01=newSale();
Salesale02=newSale();
Salesale03=newSale();
//修改线程的名字,后续会详讲(修改线程名字要在开启线程之前)sale01.setName("窗口01");
sale02.setName("窗口02");
sale03.setName("窗口03");
sale01.start();
sale02.start();
sale03.start();
    }
}
classSaleextendsThread{
//将票数声明为static表示,当前票数是当前类共享的privatestaticintticket=100;
@Overridepublicvoidrun() {
while (true){        
if (ticket>0) {
//因为当前类继承了Thread类,所以可以直接调用getName()获取当前线程的名字         System.out.println(getName() +"_票号为:"+ticket);
ticket--;
                } else {
break;
                }
            }
        }
}


相关文章
|
1天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
9 0
|
1天前
|
设计模式 消息中间件 安全
【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列
【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列
8 0
|
1天前
|
安全 Java 程序员
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
5 0
|
1天前
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
9 1
|
1天前
|
Java
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
9 1
|
1天前
|
存储 缓存 安全
【Java多线程】线程安全问题与解决方案
【Java多线程】线程安全问题与解决方案
8 1
|
1天前
|
Java 调度
【Java多线程】线程中几个常见的属性以及状态
【Java多线程】线程中几个常见的属性以及状态
7 0
|
1天前
|
Java 调度
【Java多线程】对进程与线程的理解
【Java多线程】对进程与线程的理解
9 1
|
3天前
|
存储 安全 Java
【探索Linux】P.21(多线程 | 线程同步 | 条件变量 | 线程安全)
【探索Linux】P.21(多线程 | 线程同步 | 条件变量 | 线程安全)
9 0
|
3天前
|
算法 安全 Linux
【探索Linux】P.20(多线程 | 线程互斥 | 互斥锁 | 死锁 | 资源饥饿)
【探索Linux】P.20(多线程 | 线程互斥 | 互斥锁 | 死锁 | 资源饥饿)
9 0