java中关于多线程的使用(一)

由于多线程的使用涉及的比较多,就以两篇文章来进行记录了。


目录

进程与线程

1、简介

2、多线程的优点

3、实现多线程的两种方法

(1)、继承Thread

(2)、实现Runnable接口


进程与线程

1、简介

程序是计算机指令的集合,而进程就是一个运行中的程序,它指的是从代码加载,执行到执行结束这样一个完整的过程。而每个进程都是占用不同的内存空间。

线程则是进程中某个单一的顺序的控制流,也被称为轻量进程,它被操作系统调度,并在处理器或在内核上运行。一个进程都有一个主线程,一个进程也可以由多个线程组成,每条线程并行执行不同的任务,这多个线程共享一个内存空间。


2、多线程的优点

(1)、多线程技术使程序响应更快

(2)、当前没有处理任务时可以将cpu处理时间让给其他任务

(3)、需要使用大量cpu处理时间的任务可以定期将处理时间让给其他任务

(4)、可以随时停止任务

(5)、可以通过设置任务的优先级来优先处理任务


3、实现多线程的两种方法

两种方法都以售卖票为例

(1)、继承Thread

优点:编写简单。如果需要访问当前线程,无须使用Thread.currentThread()方法,直接使用this,即可获得当前线程

缺点:因为线程类已经继承了Thread类,所以不能再继承其他父类

具体步骤:

1.创建Thread子类;

2.重写Thread类中的方法;

3.创建Thread子类对象,即创建一个线程对象;

4.调用线程对象的start()方法启动线程,之后系统会自动调用重写的run()方法中的具体实现。

代码实例:

package Study;

public class Exp03 extends Thread{
    int ticket=6;
    //重写Thread类的run()方法
    public void run(){
        //持续卖票。一直到剩余票数为0
        while(this.ticket>=0){
            System.out.println(this.getName()+"卖票-->"+(this.ticket--));
        //对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
        }
    }
    public static void main(String[] args){
        Exp03 thread1=new Exp03();
        Exp03 thread2=new Exp03();
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread1.start();   //线程运行
        thread2.start();
    }
}

输出结果

需要注意的是,例子中创建了2个线程并允许,多次运行的输出结果可能不一样。因为线程是通过线程调度来执行的,就是很多线程处理就绪状态,但实际只有一个线程在运行。因此操作系统会在一个线程空闲时撤下这个线程,改让其他线程来执行,即线程调度。

 如果需要线程按照程序调用顺序来执行,必须要在执行前来判断前面的线程是否已经终止。这会在下一篇博文讲到的线程同步中出现

(2)、实现Runnable接口

优点:线程类只是实现了Runnable接口,还可以继承其他类。可以多个线程共享同一个目标对象,即非常适合多个相同线程来处理同一份资源的情况。

缺点:获取当前线程,必须使用Thread.currentThread()方法

具体步骤

1.定义实现Runnable接口的类,实现run()方法;

2.创建Runnable对象作为Thread类的target参数来创建Thread对象(实际的线程对象);

3.调用start()方法启动线程。

代码实例(2个实例,实例2利用该方法的优点对实例1进行修改):

实例1:

package Study;

public class Exp03 implements Runnable{
    int ticket=6;
    //重写Thread类的run()方法
    public void run(){
        //持续卖票。一直到剩余票数为0
        while(this.ticket>=0){
            System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
            //对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
        }
    }
    public static void main(String[] args){
        Exp03 t1=new Exp03();      //创建线程类对象
        Exp03 t2=new Exp03();
        Thread thread1=new Thread(t1);     //创建线程
        Thread thread2=new Thread(t2);
        thread1.setName("窗口1");     //给线程命名
        thread2.setName("窗口2");
        thread1.start();   //线程运行
        thread2.start();
    }
}

 输出结果

利用Runnable的优点,对实例1进行修改,实现多个线程处理同一个资源

实例2:

package Study;

public class Exp03 implements Runnable{
    int ticket=6;
    //重写Thread类的run()方法
    public void run(){
        //持续卖票。一直到剩余票数为0
        while(this.ticket>=0){
            System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
            //对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
        }
    }
    public static void main(String[] args){
        Exp03 t1=new Exp03();      //创建线程类对象
        Thread thread1=new Thread(t1);     //创建线程
        Thread thread2=new Thread(t1);
        thread1.setName("窗口1");     //给线程命名
        thread2.setName("窗口2");
        thread1.start();   //线程运行
        thread2.start();
    }
}

输出结果:

 从输出结果可以看出,2个窗口同时在对一个对象t1的6张票进行销售,因此2个窗口总共卖出6张票,而不是实例1的12张票。

因此在用多线程处理共用资源的时候非常适合采用Runnable接口的方法

猜你喜欢

转载自blog.csdn.net/weixin_47406082/article/details/123811444
今日推荐