java并发编程之多线程基础

什么是线程?

 答:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位---------------------->个人认为是在一个程序中(进程)的一个独立,而且可以多个并行执行的一条执行路径

什么是进程?

答:进程是由多个线程实例组成的一组线程的集合,它可以看出是一个程序运行的实例

线程和进程的区别?

答:到了这里应该很明确了,线程是一组线程的一个集合,线程是一个进程中的一个独立的可以并行执行的一个执行路径。

回到我们的主题:多线程

顾名思义,多线程就是很多个线程,那么线程的特点是什么,可以并行执行,而且是一条独立的执行路径。

那么我们可以看出多线程的优点:提高程序的执行效率,如果还不理解,那么我们就举个栗子:

通过上面的图,我们可以很清晰的看到,货物a之后一个卡车在拉货,完成任务需要五个小时,但是货物b是三个卡车在拉货,而且每个卡车都有属于自己的道路,也就不会存在堵车的情况,那么效率会相对于货物a大大提高。那么多线程的优点久跟这个原理一样。可以提高程序执行效率。

那么多线程真的是同时在进行执行吗?其实多线程不是在同时执行的,多线程会进行对CPU的抢渡,多个线程在就绪状态之后,CPU会进行随机分配资源,那个线程拿到资源就可以进行执行,当然这是非常非常短暂的一个时间,我们几乎是可能感觉得到得,所以才说是在并行进行执行,而且是独立的,也就是说线程与线程之间是互不影响的,

总结:就是线程是CPU随机进行分配资源,拿到资源的才可以进行运行,但是时间是非常短的,所以对于我们可以说是同时进行执行的,其次,就是线程是独立的互不影响的

凡事都是物极必反的,多线程同样如此,就拿上图来说把,虽然我们这里使用了三个卡车进行执行,效率变快了,但是也需要老板有哪个实力啊,如果你没有那么多钱,还叫那么多卡车,最后会导致什么结果,多线程也是如此,就算线程能提高程序执行效率,但是也不能盲目的使用,要根据自己的硬件也就是CPU进行合理分配才行。

多线程使用场景:执行比较耗时,但是又不希望影响到主线程的东西,比如下载,数据库连接池等

好了下面我们就开始在java中使用多线程

首先我们得了解一下如何创建一个多线程,多线程的创建方式有很多,这里列举三个:

1:继承Thread类

class CreateThread extends Thread {
	// run方法中编写 多线程需要执行的代码
	publicvoid run() {
		for (inti = 0; i< 10; i++) {
			System.out.println("i:" + i);
		}
	}
}
publicclass ThreadDemo {

	publicstaticvoid main(String[] args) {
		System.out.println("-----多线程创建开始-----");
		// 1.创建一个线程
		CreateThread createThread = new CreateThread();
		// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
		System.out.println("-----多线程创建启动-----");
		createThread.start();
		System.out.println("-----多线程创建结束-----");
	}

}

那么执行结果为:

为什么出现这种情况:那是因为线程是独立的一条执行路径,上面的代码中存在两个线程,其中main方法是主线程,我们自定义的类是子线程,由于主线程之中的东西非常少,所以在我们子线程还没有执行完毕我们的主线程就执行完毕了,所以才会有这样的结果。

2:实现Runnable接口

class CreateRunnable implements Runnable {

	@Override
	publicvoid run() {
		for (inti = 0; i< 10; i++) {
			System.out.println("i:" + i);
		}
	}

}


publicclass ThreadDemo2 {
	publicstaticvoid main(String[] args) {
		System.out.println("-----多线程创建开始-----");
		// 1.创建一个线程
		CreateRunnable createThread = new CreateRunnable();
		// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
		System.out.println("-----多线程创建启动-----");
		Thread thread = new Thread(createThread);
		thread.start();
		System.out.println("-----多线程创建结束-----");
	}
}

这上面的运行结果跟继承thread类的差不多,同理

3:匿名内部类方式

public class CreateThread {

    public static void main(String[] args) {
        System.out.println("主线程开始执行");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程开始执行");
                for (int i = 0 ; i < 10 ; i++){
                    System.out.println("i:"+i);
                }
                System.out.println("子线程执行结束");
            }
        });
        thread.start();
        System.out.println("主线程执行完毕");
    }
}

执行结果,同理

----多线程推荐事项继承Runnable接口,我们还是要面向接口编程哈

另外启动多线程是thread.start(),很多初学的小伙伴会认为是thread.run(),run()方法只是人家多线程执行的一个入口,我们需要使用多线程执行的东西就是放在run方法里面的,但是启动多线程还是使用thread.start()

我们创建了多线程,并且可以输出打印一段话了,那么多线程的执行流程是如何的,那就要说到我们线程的五个状态,创建就绪运行阻塞销毁

创建:就是我么创建了一个Thread的实例,但是没有做任何操作

就绪:即是我们调用thread.start()方法,因为前面也说了,线程的运行是拿到CPU的资源之后才会执行,没拿到就会进行等待,所以说调用thread.start()是就绪状态,因为这之间的时间是非常短暂的,所以往往调用了thread.start()就会执行,让人误以为thread.start()就是启动线程

运行:这个时候线程拿到了CPU的资源,进行执行run方法了

阻塞:这种情况就是线程在一些情况下停止了继续往后面执行,比如等待别的真正使用的锁,使用sleep方法,等很多

销毁:当线程发生未捕获的错误,或者正常执行完毕之后,线程就会进行销毁

常用线程api方法

start()

启动线程

currentThread()

获取当前线程对象

getID()

获取当前线程ID      Thread-编号  该编号从0开始

getName()

获取当前线程名称

sleep(long mill)

休眠线程

Stop()

停止线程,

isAlive()

如果线程是正在允许或者被阻塞返回true,如果是没有就绪或者死亡的线程返回false

Join()

可以让一个线程优先执行

setPriority()

设置线程的优先级,也就是获取CPU的可能性会更大,但是可能看不出效果,可以传递0~10

常用线程构造函数

Thread()

分配一个新的 Thread 对象

Thread(String name)

分配一个新的 Thread对象,具有指定的 name正如其名。

Thread(Runable r)

分配一个新的 Thread对象

Thread(Runable r, String name)

分配一个新的 Thread对象

另外可以使用idea工具点击进入Thread类,可以看到更多。

发布了25 篇原创文章 · 获赞 9 · 访问量 3058

猜你喜欢

转载自blog.csdn.net/qq_40053836/article/details/99686777