线程的创建
Posted 姚龔子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程的创建相关的知识,希望对你有一定的参考价值。
进程:就是正在运行的程序 (一个进程可以有多个线程),分配内存让应用程序能够运行。
Windows系统号称多任务(可以同时运行多个应用程序)
宏观上看:Windows确实运行了多个程序
围观上看:cpu快速做了切换操作,快速执行任务
线程:线程就是在一个进程中负责代码的执行,就是一个进程中的执行路径
java程序在运行的时候,java虚拟机会帮我们创建一个主线程来执行代码,主线程主要负责main里面的代码
一个java程序里面,至少有两个线程,一个是主线程,主要负责main方法的执行,另外一个是垃圾回收器线程,主要负责垃圾回收
多线程:在一个进程中,多个线程同时执行不同的任务,(就是单核cpu在做快速的切换,多个线程执行任务)
多线程的好处:
1.可以解决一个进程中同事执行多个任务的问题
2.提高资源的利用率
多线程的弊端:
1.增加cpu的负担,不是线程越多越好
2.降低了一个进程中线程的执行
3.容易引发线程安全问题
4.容易出现死锁
java中创建线程有两种方式:
方式一: Thread (线程类)
1.需要定义一个类来继承Thread类
2.重写Thread类中的run方法,把自定义线程的任务代码写在run方法中,每一个线程都有自己的任务代码,java虚拟机创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写下run方法中,自定义的线程就需要来执行run方法中的代码
3.创建Thread的子类,并且调用start方法开启线程
注意点:一旦线程开启了,会默认执行线程对象中的run方法,但是千万不要自己直接调用run方法,如果直接调用run方法,就和普通的方法没有区别
线程的生命周期:
创建线程(new子线程类)——>等待运行状态(只有cpu的等待资格,没有执行)——>运行状态(具备cpu的执行权,具备cpu的等待权)
——>结束
线程如果执行sleep或者wait方法,那么这个时候线程会处于阻塞状态,如果是sleep方法,如果超过了睡眠时间线程会立马进入等待运行状态,如果是wait,需要通过其他的线程来唤醒
线程常用的方法:
Thread (String name)初始化线程名字
getName() 返回线程的名字
setName(String name)设置线程对象名字
sleep() 线程睡眠指定毫秒数
getPriority 获取主线程的优先级,默认线程的优先级是5,
setPriority(int newPriority)设置线程的优先级,虽然设置了线程的优先级,但是具体的实现取决于底层的操作系统的实现(最大的优先级是10,最小的优先级是1,一般默认是5)
currentThread()返回cpu正在执行的线程对象
出现了线程安全问题,数据操作不安全
java给线程枷锁:
方式一:同步代码块
所对象可以是人任意一个java中的对象 java中的任意一个对象,都会有一个对象的状态,,就可以通过对象的状态来作为锁的一个标识符,statue = 0 ,表示锁是关闭的 statue = 1,表示锁打开的
synchronized(锁对象){
}
同步代码块的使用注意点:
1.任意一个对象都可以做锁对象
2.如果你在同步代码块中调用了sleep方法,不会释放锁对象
3.只有真正的存在线程安全的时候才需要使用同步代码块的方法,否则会降低执行效率
4.多线程操作锁对象必须是唯一的,否则无效
出现线程安全问题根本原因:
1.存在两个或两个以上的线程,并且线程之间共享看一个资源
2.多个语句操作共享资源
方式二:同步函数,用关键字synchronized 修饰函数:
同步函数有锁方法,
同步函数注意点:
1.如果是一个非静态的函数,同步函数的锁对象就是调用方法的对象(this对象),如果是一个静态函数同步函数的锁对象,是当前函数所属类的字节码(class 对象)
2.同步函数的锁对象固定,不能够自己来指定
3.同步函数是同步整个函数的代码。
推荐使用:同步代码块
原因:
1.同步代码块的锁对象可以由我任意指定,同步函数是固定的
2.同步代码块可以控制同步的范围,同步函数必须是整个函数的所有代码都被同步
代码同步是可以解决线程安全问题,但是如果使用不当会导致线程死锁问题
A线程等B线程 B有要等A线程,两个人就等到一起了 或造成死锁的
线程的定义方式二:
1. 定义一个类实现Runable接口,接口就会提供一个run方法
2.实现Runbale接口的run方法,将线程中的任务写在run方法中
3.创建RUnbale接口的实现类对象
4.创建一个Thread对象,并把Runable实现类的创建的对象做为参数
5.调用Thread对象的start方法开启线程
问题: 为什么要将Runable接口实现类的对象做为参数传递?
为了让对象中的run方法能够在线程中的run方法中执行,也就是能够将对象中的run方法做为线程中的任务来执行
线程的通讯:一个线程完成自己的任务;去通知另外一个线程完成另外一个任务
wait();等待 如果线程执行了wait方法,那么该线程就会处于一个等待状态,等待状态的线程必须要通过其他线程来调用
notify()方法来唤醒
notify();唤醒 随机唤醒一个
notifyAll();唤醒所有的等待
1.wait方法和notify方法是属性object对象
2.wait方法和notify方法必须在同步线程中执行
3.wait方法和notify方法必须有所对象来调用
以上是关于线程的创建的主要内容,如果未能解决你的问题,请参考以下文章