线程简介:任务,进程,线程,多线程;
进程:一进程中可以包括若干个线程, 一个进程中至少有一个线程,否则没有存在的意义。
线程:CPU调度和执行的单位
通常在一个进程中可以包含多个线程。
很多多线程是模拟出来的,真正的多线程是指由多个CPU,即多核,如服务器,如果模拟出来的多线程,即在一个CPU下
在同一个时间点,CPU只能执行一个代码,因为切换的很快,所以有同时执行的错觉
线程就是独立的执行路径:
在程序运行时,即使没有自己创建线程,后台也会有多个线程,如:主线程,gc线程
main()称之为主线程,为系统的入口,用于执行整个程序;
在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度器是与操作系统紧密相关的先后顺序是不能认为的干预
对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
线程会带来额外的开销,如CPU调度时间,并发控制开销。
每一个线程在自己的工作内存交互,内存控制不当会造成数据不一致
线程创建(Thread ,
Runnable ,Callable)
线程开启不一定立即执行,由cpu调度执行
public class Demo extends Thread{
//创建线程的方式:继承Thread类,重写run()方法,调用start方法 开启线程
public void run(){//run方法线程体
for (int i = 0;i<50;i++){
System.out.println("这是run线程" +i);
}
}
public static void main(String[] args) {
//创建一个线程对象
Demo deme = new Demo();
//调用start方法开启线程
deme.start();
for (int i = 0;i<50;i++){
System.out.println("这是main线程" +i);
}
}
}
实现Runnable接口
public class Tickat implements Runnable{
private int num = 100;
Object obj = new Object();
@Override
public void run() {
while(true){ //千万别同步
show();
}
}
public synchronized void show(){
if (num>0){
try{
Thread.sleep(10);
}
catch (InterruptedException e){
}
System.out.println(Thread.currentThread().getName()+"....sale..."+num--);
}
}
public static void main(String[] args){
Tickat T = new Tickat();
Thread T1 = new Thread(T);
Thread T2 = new Thread(T);
Thread T3 = new Thread(T); //剩下两个线程 一个是在同步函数里面 一个是在同步代码块
Thread T4 = new Thread(T);
T1.start();
T2.start();
T3.start();
T4.start();
}
}
多线程引发的并发问题
同步!
多线程安全问题产生的原因:
- 1.多个线程在操作共享的数据
- 2.操作共享数据的线程代码有多条
- 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算
- 解决思路:
- 就是讲多操作共享数据的线程代码封装起来,当有线程执行这些代码的时候
- 其他的线程的不可以参与运算
- 必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算
- 同步代码块格式
- synchronized(对象){
-
需要被同步的代码
- }
- 同步的好处: 解决了线程的安全问题。
- 同步的弊端: 相对降低了效率,因为同步外的线程的都会判断同步锁
- 同步的前提: 必须有多个线程并使用同一个锁
- 同步的函数: 使用的锁是this