Java筑基29-线程01-概念&使用&常用方法

目录

一、线程介绍

1.程序

2.线程相关概念

1)什么是进程?

2)什么是线程?

3)单线程&多线程

二、线程使用

1.继承Thread类

为什么是start?

多线程机制

2.实现Runnable接口

说明

使用代理模式模拟

多线程执行案例

3.线程如何理解

4.继承Thread和实现Runnable区别

5.售票案例

6.线程退出

三、线程常用方法

1.线程中断

2.线程插队

练习题:

3.守护线程


一、线程介绍

1.程序

为完成特定任务,用某种语言编写的一组指令的集合。简单来说就是我们写的代码。

2.线程相关概念

1)什么是进程?

2)什么是线程?

3)单线程&多线程

4)并发&并行

查看Cpu处理个数:

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class CpuNum {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        int i = runtime.availableProcessors();
        System.out.println(i);//8
    }
}

二、线程使用

创建线程的两种方式:

Ⅰ.继承Thread类,重写run()方法

Ⅱ.实现Runnable接口,重写run()方法

1.继承Thread类

继承关系图:

应用案例:编写一个线程,每个一秒,控制台输出“我是一只可爱喵”,并用Jconsole监控线程执行情况。

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class Thread01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.start();
    }
}
class Cat extends Thread{
    @Override
    public void run() {
        int i=0;
        while(true){
            System.out.println("我是一只可爱喵" + (++i));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if(i==80)
                break;
        }
    }
}

输出:

我是一只可爱喵1

我是一只可爱喵2

我是一只可爱喵3

...

我是一只可爱喵79

我是一只可爱喵80

2.多线程机制

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class Thread02 {
    public static void main(String[] args) {
        Cat2 cat = new Cat2();
        cat.start();

        System.out.println("主线程继续执行" + Thread.currentThread().getName());
        for (int i = 1; i <= 60; i++) {
            System.out.println("我是主线程" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class Cat2 extends Thread{
    @Override
    public void run() {
        int i=0;
        while(true){
            System.out.println("我是一只可爱喵" + (++i));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if(i==80)
                break;
        }
    }
}

输出:

主线程继续执行main

我是一只可爱喵1

我是主线程1

我是主线程2

我是一只可爱喵2

我是一只可爱喵3

...

我是一只可爱喵79

我是一只可爱喵80

为什么是start?

直接调run方法行不行?

package com.feiyang.basic13;

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class Thread02 {
    public static void main(String[] args) {
        Cat2 cat = new Cat2();
        cat.start();
        //cat.run();

        System.out.println("主线程继续执行" + Thread.currentThread().getName());
        for (int i = 1; i <= 60; i++) {
            System.out.println("我是主线程" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class Cat2 extends Thread{
    @Override
    public void run() {
        int i=0;
        while(true){
            System.out.println("我是一只可爱喵" + (++i) + ",线程名:" +Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if(i==80)
                break;
        }
    }
}

演示:cat.start();

输出:

主线程继续执行main

我是一只可爱喵1,线程名:Thread-0

我是主线程1

我是一只可爱喵2,线程名:Thread-0

我是主线程2

我是主线程3

我是一只可爱喵3,线程名:Thread-0

我是一只可爱喵4,线程名:Thread-0

演示:cat.run();

输出:

我是一只可爱喵1,线程名:main

我是一只可爱喵2,线程名:main

我是一只可爱喵3,线程名:main

start创建新线程,直接调用run方法并不会创建新线程

多线程机制

①main方法启动后会进入start方法

public synchronized void start() {

start0();

}

②start方法中有start0()方法,该方法是真正的实现多线程,

start0是native,本地方法,由JVM调用,底层是c/c++实现

private native void start0();

2.实现Runnable接口

说明

①java是单继承的,某些情况下,一个类已经继承了某个父类,此时再继承Thread类显然是不可能的。

②java设计者提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class Thread02 {
    public static void main(String[] args) {
        T2 t2 = new T2();
        Thread thread = new Thread(t2);
        thread.start();
    }


}

class T2 implements Runnable{
    int times = 0;

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hi!" + (++times));
            if(times==10){
                break;
            }
        }
    }
}

输出:

hi!1

hi!2

hi!3

...

hi!9

hi!10

使用代理模式模拟

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:使用代理模式模拟
 */
public class ThreadProxyAgency {
    public static void main(String[] args) {
        Dog dog = new Dog();
        ThreadProxy threadProxy = new ThreadProxy(dog);
        threadProxy.start();
    }
}

class ThreadProxy implements Runnable{
    private Runnable target = null;
    @Override
    public void run() {
        if(target != null){
            target.run();
        }
    }

    public ThreadProxy(Runnable target){
        this.target = target;
    }

    public void start(){
        start0();
    }

    public void start0(){
        run();
    }
}

class Dog implements Runnable{
    int times = 0;

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hi!" + (++times));
            if(times==10){
                break;
            }
        }
    }
}

输出:

hi!1

hi!2

hi!3

...

hi!9

hi!10

多线程执行案例

package com.feiyang.basic13;

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class Thread04 {
    public static void main(String[] args) {
        T3 t3 = new T3();
        T4 t4 = new T4();
        Thread thread1 = new Thread(t3);
        Thread thread2 = new Thread(t4);
        thread1.start();
        thread2.start();
    }

}

class T3 implements Runnable{
    int times1;
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello,wold" + (++times1));
            if(times1 == 10){
                break;
            }
        }
    }
}

class T4 implements Runnable{
    int times2;
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hi" + (++times2) );
            if(times2 == 5){
                break;
            }
        }
    }
}

输出:

hello,wold1

hi1

hi2

hello,wold2

hi3

hello,wold3

hello,wold4

hi4

hello,wold5

hi5

hello,wold6

hello,wold7

hello,wold8

hello,wold9

hello,wold10

3.线程如何理解

4.继承Thread和实现Runnable区别

5.售票案例

会有超卖,重复卖问题,下章会讲如何解决

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class SellTicket {
    public static void main(String[] args) {
        Sell sell = new Sell();
        new Thread(sell).start();
        new Thread(sell).start();
        new Thread(sell).start();
    }

}

class Sell implements Runnable{
    static int ticket = 100;
    @Override
    public void run() {
        while(true){
            if(ticket <= 0){
                break;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口" + Thread.currentThread().getName()+"卖出了一张票,剩余" + (--ticket) );
        }
    }
}

6.线程退出

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ThreadExit {
    public static void main(String[] args) {
        T t = new T();
        Thread thread = new Thread(t);
        thread.start();

        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.setExit(false);
        System.out.println("Thread退出了");
    }
}

class T implements Runnable{
    int times2;
    private boolean exit = true;
    @Override
    public void run() {
        while(exit){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread继续运行" + (++times2) );
        }
    }

    public void setExit(boolean exit) {
        this.exit = exit;
    }
}

输出:

Thread继续运行1

Thread继续运行2

Thread继续运行3

Thread继续运行4

Thread继续运行5

Thread继续运行6

Thread退出了

三、线程常用方法

1.线程中断

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class ThreadMethod01 {
    public static void main(String[] args) throws InterruptedException {
        T1 t1 = new T1();
        t1.setName("老王");
        t1.setPriority(Thread.MIN_PRIORITY);
        t1.start();

        for (int i = 1; i <= 3; i++) {
                Thread.sleep(1000);
                System.out.println(i + "秒");
        }
        System.out.println("都休息三秒了,起来继续吃~");
        t1.interrupt();

    }
}

class T1 extends Thread{
    int count = 0;
    @Override
    public void run() {
        while(true){
            for (int i = 1; i <= 3; i++) {
                System.out.println(Thread.currentThread().getName() + "开始吃包子~" + i);
            }
            try {
                System.out.println(Thread.currentThread().getName()+"太累了休息5秒~");
                Thread.sleep(5*1000);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName()+"被中断了");
            }
            count++;
            if(count==3){
                System.out.println("吃撑了,不吃了哈~");
                break;
            }
        }
    }
}

输出:

老王开始吃包子~1

老王开始吃包子~2

老王开始吃包子~3

老王太累了休息5秒~

1秒

2秒

3秒

都休息三秒了,起来继续吃~

老王被中断了

老王开始吃包子~1

老王开始吃包子~2

老王开始吃包子~3

老王太累了休息5秒~

老王开始吃包子~1

老王开始吃包子~2

老王开始吃包子~3

老王太累了休息5秒~

吃撑了,不吃了哈~

2.线程插队

/**
 * @author: 程序员飞扬
 * @公众hao:程序员飞扬
 * @微xin:haris7799
 * @description:
 */
public class ThreadMethod02 {
    public static void main(String[] args) throws InterruptedException {
        T5 t5 = new T5();
        t5.start();

        for (int i = 1; i <= 5; i++) {
                Thread.sleep(1000);
                System.out.println("小弟吃包子" + i);
                if(i==3){
                    System.out.println("小弟已经吃了3了个,让老大先吃饱~~~");
                    t5.join();//线程插队,相当于让t5先执行完
                    //Thread.yield();//礼让,但不一定礼让成功
                }
        }
    }
}

class T5 extends Thread{
    @Override
    public void run() {
        try {
            for (int i = 1; i <= 8; i++) {
                System.out.println("老大开始吃包子" + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {

        }
    }
}

输出:

老大开始吃包子1

老大开始吃包子2

小弟吃包子1

老大开始吃包子3

小弟吃包子2

老大开始吃包子4

小弟吃包子3

小弟已经吃了3了个,让老大先吃饱~~~

老大开始吃包子5

老大开始吃包子6

老大开始吃包子7

老大开始吃包子8

小弟吃包子4

小弟吃包子5

练习题:

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ThreadMethodExcrcise {
    public static void main(String[] args) throws InterruptedException {
        T6 t6 = new T6();
        Thread t = new Thread(t6);
        for (int i = 1; i <= 10; i++) {
            System.out.println("hi" + i);
            Thread.sleep(1000);
            if(i==5){
                t.start();
                t.join();
            }
            if(i==10){
                System.out.println("主线程结束");
            }
        }
    }
}

class T6 implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println("hello" + i);
            if(i==10){
                System.out.println("子线程结束");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

输出:

hi1

hi2

hi3

hi4

hi5

hello1

hello2

hello3

hello4

hello5

hello6

hello7

hello8

hello9

hello10

子线程结束

hi6

hi7

hi8

hi9

hi10

主线程结束

3.守护线程

setDaemon(true)

/**
 * @author:程序员飞扬
 * @公众hao:程序员飞扬
 * @description:
 */
public class ThreadMethod03 {
    public static void main(String[] args) throws InterruptedException {
        MyDaemonThread myDaemonThread = new MyDaemonThread();
        myDaemonThread.setDaemon(true);
        myDaemonThread.start();
        for (int i = 1; i <= 50 ; i++) {
            Thread.sleep(50);
            System.out.println("宝宝在辛苦的拍电影。。。");
        }
    }
}

class MyDaemonThread extends Thread{
    @Override
    public void run() {
        for(;;){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("蓉蓉和喆喆在快乐的聊天,哈哈哈~");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员飞扬

赠人玫瑰,手有余香,感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值