Java多线程编程基础(1)

多线程基础

  • 线程的启动,暂停,停止
  • 线程的优先级
  • 线程的安全性

什么是多线程,线程与进程

  1. 线程:线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
  2. 进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础

Java 实现多线程

  1. 继承Thread类,重写run方法
  2. 实现Runnable接口

使用第一种局限在于不可多继承,需要多继承可以使用第二种方式。
Thread本质就是实现Runnable接口。

public
class Thread implements Runnable {}

以下是通过第一种方式完成。

public class ThreadApp {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        mt.start();
        System.out.println("执行结束");
    }
}

我的线程

public class MyThread extends Thread {

    @Override
    public void run() {
        super.run();
        System.out.println("我的线程...");
    }
}

在这里插入图片描述

分析线程信息

public class ThreadApp2 {
    public static void main(String[] args) {
        System.out.println("s-----s");
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    System.out.println("1-----1");
                    Thread.sleep(500000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

在这里插入图片描述
输入jstack -l 34646,推荐使用jmc可视化分析信息。

下载地址:https://www.oracle.com/java/technologies/javase/products-jmc8-downloads.html
关于使用,远程授权等方式,请查看博客。

MacOS安装jmc注意,启动报错,请在Info.plist添加下面的路径(下面2句)

	<key>Eclipse</key>
	<array>
		<string>-keyring</string>
		<string>~/.eclipse_keyring</string>
		<string>-vm</string>
		<string>/Library/Java/JavaVirtualMachines/jdk1.8.0_281.jdk/Contents/Home/jre</string>
	</array>

在这里插入图片描述
运行程序后,查看分析器。
在这里插入图片描述

实现Runnable

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable ----");
    }
}

运行

public class ThreadApp3 {

    public static void main(String[] args) {
        Runnable mr = new MyRunnable();
        Thread thread = new Thread(mr);
        thread.start();
        System.out.println("结束");
    }
}

多线程变量安全问题

场景安排:
3名售货员出售5件货物。

  1. 数据不共享,他们每个人都5件货物
  2. 数据共享,卖的是同5件货物

代码模拟如下:

public class MyThread3 extends Thread {

    private int count = 5;

    public MyThread3(String name) {
        super();
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        while (count > 0) {
            count--;
            System.out.println("通过" + currentThread().getName() + "计算,count=" + count);
        }
    }
}

运行

public class ThreadApp5 {

    public static void main(String[] args) {
        MyThread3 mt1 = new MyThread3("A");
        MyThread3 mt2 = new MyThread3("B");
        MyThread3 mt3 = new MyThread3("C");
        mt1.start();
        mt2.start();
        mt3.start();
        System.out.println("结束");
    }
}

结果

通过B计算,count=4
通过A计算,count=4
通过A计算,count=3
通过C计算,count=4
通过C计算,count=3
通过C计算,count=2
结束
通过C计算,count=1
通过A计算,count=2
通过B计算,count=3
通过A计算,count=1
通过A计算,count=0
通过C计算,count=0
通过B计算,count=2
通过B计算,count=1
通过B计算,count=0

Process finished with exit code 0

可以看出每个线程数据不共享,自己计算自己的,那么通过数据共享呢?

public class ThreadApp6 {

    public static void main(String[] args) {
        MyThread4 myThread = new MyThread4();
        Thread mt1 = new Thread(myThread, "A");
        Thread mt2 = new Thread(myThread, "B");
        Thread mt3 = new Thread(myThread, "C");
        mt1.start();
        mt2.start();
        mt3.start();
        System.out.println("结束");
    }
}
通过B计算,count=2
通过B计算,count=1
通过B计算,count=0
通过A计算,count=2
通过C计算,count=2

发现数据出现了重复减少,这样就造成了数据安全问题,即非线程安全。通过添加synchronized实现线程排队。

结束
通过A计算,count=4
通过A计算,count=3
通过A计算,count=2
通过A计算,count=1
通过A计算,count=0

停止线程

  1. interrupt+异常停止
  2. interrupt+return停止

不可使用stop

暂停和恢复线程

  1. wait()
  2. notify()
public static void main(String[] args) {
    new Thread(() -> {
        long bt = System.currentTimeMillis();
        int count = 0;
        for (int i = 0; i < 500000; i++) {
            Thread.yield();
            count = count + (i + 1);
        }
        long et = System.currentTimeMillis();
        System.out.println("用时:" + (et - bt));
    }).start();
}

Thread.yield() 用法:放弃当前cpu,让其他任务去占用。

线程的优先级

可以通过setPriority完成设置,1-10,但是优先级还是具有随机性。

守护线程

当线程只剩下守护线程的时候,JVM就会退出。守护线程最典型的应用就是 GC (垃圾回收器)。

通过设置setDaemon(true)设置守护线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值