Java基础学习day16【谷】

本文深入讲解Java中的线程概念,包括进程、线程的区别,多线程的创建方式,如通过继承Thread类和实现Runnable接口。通过实例展示了线程的启动、线程方法如start()、run()、yield()、join()等的使用,并探讨了线程优先级和同步问题。同时,通过代码演示了如何处理多个线程共享资源的问题,如三个窗口共同卖票的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java基础学习day16

程序时一段静态代码

进程是程序的一次执行过程,正在执行的程序

线程是一个程序内部的一条执行路径

多线程的创建

  1. 创建一个继承Thread的子类
  2. 重写Tread父类的run方法
  3. 创建Thread的子类对象
  4. 通过对象调用start()方法
    • 启动当前线程
    • 调用当前线性的run方法
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i = 1; i < 100; i++) {
            if (i%2==0){
                System.out.println(i+"*");
            }
        }
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i < 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            }
        }
    }
}

问题一:我们不能通过子类对象直接调用run方法来启动线程

因为我们只是执行了类的方法,start则是创建一个线程,在本线程中调用run()方法

问题二:再启动一个线程,遍历100以内的偶数。不可以还让已经start()的线程去执行。

不行的,start只会创建一次线程,如果再次执行将会报线程不合法异常

处理办法重新new一个子类对象,调用父类的start方法

练习

创建两个线程一个遍历100以内偶数,一个遍历100以内奇数(匿名内部类方式)

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    if(i%2!=0){
                        System.out.println(Thread.currentThread().getName()+"---"+i);
                    }
                }
            }
        }.start();
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+"***"+i);

            }
        }
    }
}

测试Thread中常用方法

1.start():启动当前线程;调用当前线程run ()

2.run():通常需要重写Thread中的此方法,将创建线程需要的操作写在此方法体中

3.yield():释放当前cpu的执行权,不意味着一定不执行当前线程,可能又会重新分配给当前线程

4.join():在线程a中调用线程b的join()方法,此时a线程将变为阻塞状态,知道线程b完全执行完以后,线程a才结束阻塞状态

5.stop():已过时,不推荐使用,强制结束当前线程

6.sleep(long millitime):让当前线程睡眠指定的millitime毫秒。指定的millitime毫秒内,当前线程为阻塞状态

7.currentThread():静态方法,返回执行当前代码的线程

8.getName():获取线程名字

9.setName():设置线程名字(也可以通过构造器设置名字)

10.isAlive():判断当前线程是否存活

线程的优先级:

MAX PRIORITY:10
MIN PRIORITY:1
NORM PRIORITY:5–>默认优先级
2.如何获取和设置当前线程的优先级:
getpriority():获取线程的优先级
setpriority(int p):设置线程的优先级
说明:高优先级的线程要枪占低优先级线程CPU的执行权。但是只是从率上讲,高优先级的线程高概率的情况下
被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。

例子:三个窗口共同卖100张票

public class MyThread extends Thread {
    private static int total = 100;
    @Override
    public void run() {
        while (true){
            if(total<=0){
                break;
            }else{
                System.out.println(getName()+"***"+total--);
            }
        }
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        myThread.start();
        myThread1.start();
        myThread2.start();
    }
}

多线程的创建(二)

1.创建一个实现了Runnable接口的类

2.实现类去实现Runnable中的抽象方法run()

3.创建实现类对象

4.将此对象作为参数传递到Thread类的构造器中,创建Thread类对象

5.通过Thread类的对象调用start()方法

public class ThreadTest implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"***"+i);
        }
    }

    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread thread1 = new Thread(threadTest);
        thread1.start();
    }
}

例子:三个窗口共同卖100张票

因为是将创建好的类放入Thread的构造器中,所以类只调用一次,就是100张票

public class MyThread1 implements Runnable{
    private int total = 100;
    @Override
    public void run() {
        while (true){
            if (total>0){
                System.out.println(Thread.currentThread().getName()+"***"+total--);
            }else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        MyThread1 myThread1 = new MyThread1();
        Thread thread = new Thread(myThread1);
        thread.setName("窗口1");
        thread.start();
        Thread thread1 = new Thread(myThread1);
        thread1.setName("窗口2");
        thread1.start();
        Thread thread2 = new Thread(myThread1);
        thread2.setName("窗口3");
        thread2.start();
    }
}

比较创建线程的两种方式

推荐使用继承Runnable接口的方式

原因:1.实现的当时没有类的单继承的局限性

​ 2.实现的方式更适合来处理多个线程又共享数据的情况

联系:public class Thread implements Runnable

相同的:两种方式都要重新run方法,将线程要执行的逻辑声明在run方法中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值