JAVA基础 day11 线程

在这里插入图片描述

线程

进程的一个执行路径,CPU基本调度单位。
进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。

单核:宏观同时执行,微观串行(顺序交替执行)
多核:真正意义上的并行

进程和线程的区别
• 进程是操作系统资源分配的基本单位,而线程是CPU的基本调度单位。
• 一个程序运行后至少有一个进程。
• 一个进程可以包含多个线程,但是至少需要有一个线程。
• 进程间不能共享数据段地址,但同进程的线程之间可以。

线程的组成
• CPU时间片:操作系统(OS)会为每个线程分配执行时间。

• 运行数据:
1. 堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象。
2. 栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈。

• 线程的逻辑代码。

在这里插入图片描述

创建线程

run()方法不能抛出异常;

主线程能够创建子线程
1.继承Tread的类,重写run()方法
Java虚拟机执行程序会自动创建一个主线程(main),可以使用主线程创建子线程
启动前程,使用start()方法,不能使用run(),使用run相当于主线程调用类的方法,这种只有主线程在执行。

获取线程ID和名称
名称可修改,ID只能获取

获取方式:
第一种方式:getId() getName()
第二种方式:Thread.cunrrentThread.getId() Thread.cunrrentThread.getName ()
第二种方法较好,使用灵活

修改线程名称:
第一种:setName()
第二种:构造方法 super(name)

 	public MyThread1(String name){
        super(name);
    }

内存结构
线程创建时内存(线程没启动,各自的栈还没生成)
在这里插入图片描述

线程启动,创建各自的栈空间,各自在自己的栈空间内执行自己的run方法
在这里插入图片描述
虚线不是指向,而是表示在操作这个变量

2.实现Runnable接口 优先选择
可运行类(封装了了线程要执行的功能,任务)
实现Runnable接口,就相当于任务,把任务交给线程去处理,所以既能一起处理(共享资源),也可以单独处理(独享资源)。而继承Thread,只能单独处理(独享资源)。所以优先选择。

thread的run方法:
在这里插入图片描述

public class TestRunnable {
    public static void main(String[] args) {
        Ticket1 ticket1 = new Ticket1();
        Thread chichi1 = new Thread(ticket1, "chichi1");
        Thread chichi2 = new Thread(ticket1, "chichi2");
        Thread chichi3 = new Thread(ticket1, "chichi3");
        Thread chichi4= new Thread(ticket1, "chichi4");
        chichi1.start();
        chichi2.start();
        chichi3.start();
        chichi4.start();
    }
}
class Ticket1 implements Runnable{
    private int ticket=100;
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (ticket<=0){
                break;
            }
            else {
                System.out.println(Thread.currentThread().getName()+"卖出了"+count);
                ticket--;
            }
        }
    }
}

四个窗口共卖100张票,资源共享;
四个线程的target都指向ticket

使用实现类创建了线程对象,start启动线程,创建各自的栈空间
在这里插入图片描述
虚线不是指向,而是表示在操作这个变量

常见方法

• 休眠(静态)(有限等待)(需要抛出异常):
• public static void sleep(long millis) • 当前线程主动休眠 millis 毫秒。

休眠之后,不会争取CPU,休眠时间到了,进入就绪状态,参与CPU的争抢
线程的sleep方法应该写在线程的run()方法里,就能让对应的线程睡眠。sleep方法只能让当前线程睡眠。调用线程实例对象t1.sleep(),睡眠的不是t1这个实例类,而是当前线程。

public class Testsleep {
    public static void main(String[] args) {
        Runnable r=new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(i+"chichi");
                }
            }
        };
        Thread thread=new Thread(r);
        thread.start();
        System.out.println(thread.currentThread().getName());
        try {
            thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(i+"main");
        }
    }
}

输出
在这里插入图片描述
虽用实例对象调用静态方法,但实际静态方法都指向的是当前对象,故使用静态方法应都写在run方法内部

• 放弃
• public static void yield() • 当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片。

放弃,谦让,把CPU的使用权让给别的线程(优先级和让出线程相同或高于让出线程),进入就绪状态,继续参与CPU的争抢。(可能会再次抢到)

• 加入:(需要抛出异常)(无限等待)
• public final void join() • 允许其他线程加入到当前线程中。

要加入的线程使用join()方法,被加入的阻塞
当前线程会阻塞,直到加入线执行结束

sleep,join要放在try,catch中使用,被捕捉错误,sleep方法中断,会抛出异常

优先级
在这里插入图片描述

setPriority()方法 设置线程的优先级
优先级高的线程表示获得cpu时间片的机会多,可在任何地方设置优先级

线程打断
线程对象.interrupt()
打断线程,被打断线程抛出InterruptedExceotion异常,只有能抛出这个异常的方法才能被打断。
在这里插入图片描述

在这里插入图片描述
守护线程
默认情况下,创建的线程都是前台线程。
要在线程开始之前设置,否则会出错

线程状态

线程安全

在这里插入图片描述

线程同步

1.同步代码块

在这里插入图片描述
临界资源对象必须是这些线程都能访问到的,并且都要访问到的,并且已经进行了初始化的引用类型(并不是要修改的值)
一般选择共享资源作为锁,多个线程必须使用同一个锁

加锁就相当于封装了一个资源或者是操作。使用完才释放。
得不到锁标记,进入阻塞状态。

在这里插入图片描述
线程的状态(阻塞) jdk1.5之后,就绪状态和运行状态合二为一。
在这里插入图片描述
一共六种
getState()方法,可返回当前状态

2.同步方法

在这里插入图片描述
非静态方法,锁的是this,方法结束后,会释放锁
静态方法,锁是 类.class(锁这个类对象)
synchronized就是针对内存区块申请内存锁,this关键字代表类的一个对象,所以其内存锁是针对相同对象的互斥操作,而static成员属于类专有,其内存空间为该类所有成员共有,这就导致synchronized()对static成员加锁,相当于对类加锁,也就是在该类的所有成员间实现互斥,在同一时间只有一个线程可访问该类的实例。

在这里插入图片描述
在这里插入图片描述

死锁

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值