你不知道的Java学习笔记20-- 多线程编程

一、进程与线程

1、进程
针对系统而言,是操作系统中的一个执行单元。
对于Windows系统来说就是一个.exe程序。

2、多进程
系统同时执行多个应用程序。
DOS单进程操作系统只能执行一个进程,一个进程执行完才能执行另一个进程。
单核CPU:每次只能执行一个程序,执行多个程序其实是在程序中不停地切换,只不过切换的速度超过了人的感知,让人觉得可以同时执行多个程序。在系统中执行的程序越多执行的速度就越慢,因为要在多个程序中不停地切换。

3、线程
线程是一个程序内部的顺序控制流,线程是针对程序(进程:一个程序代表一个进程),表示程序中一个线索。

4、多线程
程序中多个执行线索。
例如:暴风播放器可以一边下载一边看。

5、为什么有使用多线程?
使用多线程能提高程序的执行效率,提高用户的体验效果。

6、进程与线程的区别和联系
(1)每个进程都有独立的代码和数据空间,进程的切换的开销很大。
(2)同一类线程共享代码和数据空间,每个线程有独立运行的栈和程序计数器,程序切换的开销小。

二、Java中多线程实现

(一)Java中多线程实现思路
1、创建线程类
继承Thread类

实现Runnable接口

2、通过Thread类构造器来创建线程对象
Thread()
Thread(Runnable target)

3、通过start()方法激活线程对象

4、线程运行

(二)多线程实现的两种方式

1、创建线程的两种方式–线程类
(1)继承Thread类–java.lang.Thread
(2)实现Runnable接口–java.lang.Runnable

2、run()方法–线程运行体
要将一段代码(线程体)在一个新的线程上运行,该代码应该在一个线程类的run()函数中。
(1)写一个类继承Thread类,且必须重写Thread类中的run()方法。
(2)写一个类实现Runnable接口,且必须覆盖Runnable接口中的run()方法。

3、方法一:继承Thread类实现多线程

/*
 * 继承Thread类实现多线程
 * 1、定义一个类去继承Thread类并重写run()方法
 * 2、创建线程对象
 * 3、调用start()方法激活线程
 */
public class TestTread {
    public static void main(String[] args) {
        //创建线程对象mythread1
        MyThread mythread1=new MyThread();
        //通过mythread1线程对象调用线程方法Set()为线程mythread1设置名称
        mythread1.setName("线程1");

        //创建线程对象mythread2
        MyThread mythread2=new MyThread();
        //通过mythread2线程对象调用线程方法Set()为线程mythread2设置名称
        mythread2.setName("线程2");

        //调用start()方法,激活进程
        mythread1.start();
        mythread2.start();
        System.out.println(Thread.currentThread().getName()+" is over...");
    }

}
//定义一个类去继承Thread类
    class MyThread extends Thread{
        //定义常量count
        int count=100;
        //重写run()方法,run方法包含的是线程的运行代码
        public void run()
        {
            //利用for()循环进行打印
            for(int i=0;i<5;i++)
            {
//Thread.currentThread().getName()获取当前线程的名字
                System.out.println(Thread.currentThread().getName()+"\t"+count--);
            }
        }
    }

这里写图片描述

4、方法二:实现Runnable接口实现多线程

/*
 * 实现Runnable接口实现多线程
 * 1、定义一个类去实现Runnable接口并重写run()方法
 * 2、创建实现类对象
 * 3、创建线程对象
 * 4、调用start()方法激活线程
 */
public class TestRunnable {
    public static void main(String[] args) {
        //创建实现类对象
        MyRunnable runn=new MyRunnable();
        //创建线程对象,线程类Thread必须调用业务类MyRunnable--runn才能实现去干活
        Thread th1=new Thread(runn);
        //通过线程对象调用线程方法Set()为线程设置名称
        th1.setName("线程1");
        //创建线程对象,线程类Thread必须调用业务类MyRunnable--runn才能实现去干活
        Thread th2=new Thread(runn);
        //通过线程对象调用线程方法Set()为线程设置名称
        th2.setName("线程2");
        //通过线程对象调用线程方法start()为激活线程
        th1.start();
        th2.start();
        //Thread.currentThread().getName():获取当前线程的名字
        System.out.println(Thread.currentThread().getName()+" is over...");
    }
}
//、定义一个类去实现Runnable接口
class MyRunnable implements Runnable{
    //定义count常量
    int count=100;
    //重写run()方法
    public void run() {
        //利用for()循环进行打印
        for(int i=0;i<5;i++)
        {
            //Thread.currentThread().getName():获取当前线程的名字
            System.out.println(Thread.currentThread().getName()+":\t"+count--);
        }

    }

}

这里写图片描述

(三)多线程访问同一数据的问题

1、在继承Thread类实现多线程中,创建了两个对象,所以mythread1和mythread2不是公用一个数据空间的,每new一个就新建一个数据空间,一共新建了两个数据空间。count成员变量都是每个对象独有的。如果想要实现共用一个数据空间的话可以把count定义为static int count=100;但是是伪方法,在实际的开发中一般不会用。

//创建线程对象mythread1
MyThread mythread1=new MyThread();
//创建线程对象mythread2
MyThread mythread2=new MyThread();

2、在实现Runnable接口实现多线程中,创建了一个实现类对象runn,而创建的两个线程对象th1、th2都是在实现类对象runn基础上创建的,所以他们共用一个数据空间,两个线程的操作都是在同一count上,与他们执行的先后无关。

//创建实现类对象
MyRunnable runn=new MyRunnable();
//创建线程对象,线程类Thread必须调用业务类MyRunnable--runn才能实现去干活
Thread th1=new Thread(runn);
//创建线程对象,线程类Thread必须调用业务类MyRunnable--runn才能实现去干活
Thread th2=new Thread(runn);

三、比较两种实现线程方法的优劣

1、通过继承Thread实现线程,更容易理解与实现,不方便实现多进程共享同一数据空间。
2、通过实现Runnable接口创建线程,理解不易实现困难,容易实现多线程共享同一数据空间。因为它是实现接口的,所以还可以继承其他的类进行拓展。

四、线程的生命周期

1、创建

MyThread mythread1=new MyThread();

2、就绪

mythread1.start();

3、执行

run()方法

4、阻塞

sleep()、yield()

5、终止

1)run()方法执行完毕(正常结束)
(2Interrupt()结束中断进程(非正常结束)

猜你喜欢

转载自blog.csdn.net/lin434406218/article/details/52724997
今日推荐