java 多线程

进程与线程的区别

进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。

线程:是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的 资源。

Java 的线程实现

1.继承 Thread 类

一个类只要继承了 Thread 类,那么此类就可以是一个多线程的操作类,Thread 类是在 java.lang 包中定义的类,所以
此类可以自动导入并使用。单单只是继承 Thread 类还不能完成线程的功能,还必须覆写 Thread 类中的 run()方法。

lass MyThread extends Thread
private String name; // 定义属性
public MyThread(String name) {
this.name = name;
}
public void run() { // 覆写Thread类中的run()方法
for (int i = 0; i < 10; i++) {
System.out.println(this.name + " --> 运行,i = " + i);

以上的操作,已经实现了一个线程类,那么下面在主方法之中,就要求启动此线程。多个进程是同时运行的,那么
多个线程也应该是同时运行的。那么此时就需要启动线程。

public static void main(String[] args) {
new MyThread("线程A").run() ;
new MyThread("线程B").run() ;

主方法中声明了两个线程对象,那么此时就应该是两个程序同时运行。但是,此时发现,程序并不是同时运行的,
还是属于顺序执行,即:先执行完第一个对象之后,再执行第二个对象。
所以,如果要想在程序中正确的启动多线程,则必须使用 Thread 类中的 start()方法,此方法如下:
· 启动线程:public void start(),从此方法的解释上可以发现,此方法执行的时候,将由 JVM 去调用 run()
· 相当于:调用 start()  执行 run()方法。

public static void main(String[] args) {
new MyThread("线程A").start() ;
new MyThread("线程B").start() ;

注:此时,发现代码,可以完成交替的运行操作,谁抢占到了 CPU 资源,就运行那个线程。

2.实现 Runnable 接口

class MyThread implements Runnable { // 实现了Runnable接口
private String name; // 定义属性
public MyThread(String name) {
this.name = name;
}
public void run() { // 覆写Thread类中的run()方法
for (int i = 0; i < 10; i++) {
System.out.println(this.name + " --> 运行,i = " + i);

实现之后,那么该如何启动线程呢?
之前继承 Thread 类实现多线程的时候靠的是 Thread 类中的 start()方法,但是现在实现的是 Runnable 接口,此接口中
并没有 start()方法的定义,那么该如何启动呢?因为线程启动的时候必须依靠操作系统的支持,所以肯定要使用 start()方法,
此时观察 Thread 类中的构造方法:
· 接收 Runnable 子类实例的构造:public Thread(Runnable target)
可以通过 Runnable 子类的对象构建 Thread 类的对象,并调用 start()方法。

MyThread mt1 = new MyThread("线程A") ;
MyThread mt2 = new MyThread("线程B") ;
new Thread(mt1).start() ; // 通过Thread类启动多线程
new Thread(mt2).start() ; // 通过Thread类启动多线程

两种实现方式的区别

首先,从基本概念上看,使用 Runnable 接口更好,因为避免单继承局限
其次,使用 Runnable 接口还可以方便的实现数据的共享操作。

线程的操作状态

第一步创建一个线程的实例化对象。
第二步启动多线程,调用 start()方法,但是调用 start()方法之后并不是立刻执行多线程操作。而是跑到就绪状态。
第三步等待 CPU 进行调度,调度之后进入到运行状态。
第四步如果现在假设运行一段时间之后,被其他线程抢先了,则出现了阻塞状态,
第五步,从阻塞状态要重新回到就绪状态,等待 CPU 的下一次调度
第六步,当全部的操作执行完成之后,线程将终止执行。

注:虽然在代码上操作是有先有后,但是所有的线程肯定都是同时启动的,所以在线程的开发中没有顺序而言。
那个线程抢占到了 CPU 资源,那个线程就先执行。

取得当前的线程、设置和取得名字

在线程中可以通过 currentThread()方法取得当前正在运行的线程对象,并且可以为每一个线程对象设置和取得名字,

方法名称 类型 描述
1 public static Thread currentThread() 普通 返回当前正在执行的线程对象
2 public final String getName() 普通 取得线程的名字
3 public final void setName(String name) 普通 设置线程的名字
4 public Thread(Runnable target,String name) 构造 接收 Runnable 对象,并指定线程名称
5 public Thread(String name) 构造 为线程指定一个名字

lass MyThread implements Runnable {
    public void run() {
    for (int x = 0; x < 5; x++) { // 取得当前运行的线程名称
        System.out.println(Thread.currentThread().getName() + " --> 运行");
    }
    }
 }
public class NameThreadDemo01 {
    public static void main(String[] args) {
        MyThread my = new MyThread();
        new Thread(my, "线程A").start(); // 设置了线程名称
        new Thread(my).start(); // 没设置线程名称
        new Thread(my).start(); // 没设置线程名称
        new Thread(my, "线程B").start(); // 设置了线程名称
        new Thread(my, "线程C").start(); // 设置了线程名称
        new Thread(my).start(); // 没设置线程名称
        new Thread(my).start(); // 没设置线程名称
        new Thread(my).start(); // 没设置线程名称

发现,没有设置线程名字的线程对象所有的命名都采用“Thread-xxx”的形式出现。通过运行效果,可以得出,在
Thread 类中肯定存在一个 static 的属性,用于记录每次的增长结果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值