JAVA多线程(一)-----认识多线程

1. 认识多线程

进程和线程

  • 线程是在进程的基础上进行划分。进程是程序的一次动态执行过程,他经历了从代码加载、执行到执行完成的完整过程,这个过程也是进程本身从产生,发展到最终消亡的过程。
  • 多线程是实现并发机制的一种有效手段。进程和线程一样,都是实现并发的一个基本单位。

图片

Java的多线程实现

  • 继承Thread类
  • 实现Runnable接口
  1. Thread类

Thread类是在java.lang包中定义的,一个类只要继承了Thread类,此类就称为多线程操作类。在Threa子类之中,必须明确的覆写Thread类中的Run()方法,此方法为线程的主体。

多线程的定义语法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNguYkBc-1610103102719)(https://uploader.shimo.im/f/xBNe7j0JnuGueHI5.png!thumbnail?fileGuid=VT8YkHRTjJdQt9dG)]

案例:

class XC extends Thread{
    private String name;
    public XC(String name){
        this.name=name;
    }
    public void run(){
for(int i=0;i<10;i++){
    System.out.println(name+"运行"+(++i));}}}

我们来测试一下线程

public static void main(String[] args) {
    XC xc1=new XC("线程A");
    XC xc2=new XC("线程B");
    xc1.run();
    xc2.run();}

运行结果:
图片

运行结果是按顺序执行,并没有进行交替执行,只是因为上面的程序还是按照普通的方法调用,通过调用对象的方法,但是如果要想启动一个线程必须使用Thread类中的Start方法来启动多线程。

使用start方法后的运行结果

public static void main(String[] args) {
    XC xc1=new XC("线程A");
    XC xc2=new XC("线程B");
    xc1.start();
    xc2.start();}

图片

可以看到现在两个线程进行并发执行,那个线程先抢到cpu时间片则那个线程先执行,这里我们看一下start的实现。

图片

这里Start方法是调用run()方法,为什么我们直接调用run()方法却不能实现呢?

 public synchronized void start() {
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);}}
private native void start();

start()方法可能会抛出异常。
stopBeforeStart是一个boolean型变量。

native关键字表示的是一个由Java调用本机操作系统函数的一个关键字,在Java中运行Java程序调用本机的操作系统的函数以完成特定的功能。

如果需要实现多线程的话,则肯定需要操作系统的支持,因为多线操作中牵扯到一个抢占CPU的情况,要等待CPU进行调度,那么这一点肯定需要操作系统的底层支持,所以需要使用native调用本机的系统函数。

  1. 实现Runnable接口

在java中也可以通过实现Runnable接口的方式实现多线程,Runable接口中只定义了一个抽象的方法。

通过Runable接口实现多线程

图片

实例:

class RunDemo implements Runnable{
    private String name;
    public RunDemo(String name){
        this.name=name;
    }
    public void run(){
        for(int i=0;i<3;i++){
            System.out.println(name+"运行"+i);}}}

实现类:

public static void main(String[] args) {
    RunDemo xc2=new RunDemo("线程A");
    RunDemo xc3=new RunDemo("线程B");
    Thread t1=new Thread(xc2);
    Thread t2=new Thread(xc3);
    t1.start();
    t2.start();}

运行结果:
图片

从运行效果可以发现,已经完成了多线程的功能。

Thread与Runnable接口

两者之间的联系

public class Thread
extends Object
implements Runnable

可以看出thread实现了Runnable接口,则可知道Thread是Runable的子类。
两者之间的区别

使用Thread类在操作多线程的时候无法达到资源共享的目的,而实现Runnable接口是可以实现资源共享的。

这里我们以三个窗口卖5张票为例来进行比较。

  • 继承Thread类来进行实现
class T extends Thread{
    private int ticketN=3;
    private String name;
    public T(String name){
        this.name=name;
    }
    public void run(){
        for(int i=0;i<10;i++) {
            if (this.ticketN > 0) {
                System.out.println(name + "卖票:ticket=" + ticketN--); }}}}
public class Ticket {
    public static void main(String[] args) {
        T t1=new T("窗口A");
        T t2=new T("窗口B");
        T t3=new T("窗口C");
        t1.run();
        t2.run();
        t3.run();
    }
}

运行结果:
图片

这里可以发现每个线程都拥有独立的资源,每个线程都有3张票卖,说明资源不共享。

  • 实现Runnable的方式
class R implements Runnable{
    private int ticketN=3;
    public void run(){
        for(int i=0;i<10;i++) {
            if (this.ticketN > 0) {
                System.out.println( "卖票:ticket=" + ticketN--); }}}}

运行类:

public static void main(String[] args) {
    R r1 = new R();
    Thread t1=new Thread(r1);
    Thread t2=new Thread(r1);
    Thread t3=new Thread(r1);
    t1.run();
    t2.run();
    t3.run();}

运行结果:
图片

可以发现虽然创建了三个线程,但是三个线程一共卖出了5张票。

Thread和Runnable接口的使用结论

Runnable优点

  • 适合多个相同程序代码的下次你去处理同一个资源。
  • 可以避免由于单继承局限所带来的影响。
  • 增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的

综合runnable接口更好。

线程的状态

  • 创建状态,准备还一个多线程的实例,Thread t=newThread();
  • 就绪状态,调用start方法
  • 运行状态:调用run()方法
  • 阻塞状态,暂时停止执行,可能将资源交给其他线程使用。

图片

猜你喜欢

转载自blog.csdn.net/qq_44762290/article/details/112379256