Java多线程(一)

进程和线程的区别:
进程是程序运行的基本单位,启动一个程序就有对应的一个进程 ,例如每次运行一个Java程序就对应一个JVM进程。
线程表示程序中需要执行的任务,一个进程可以创建多个线程,对线程操作的开销比进程小的多。线程间可以共享数据,而每个进程拥有自己的一整套变量。

线程API

java.lang.Thread

线程的创建、启动(继承Thread类)

Thread类中有一个run的方法,继承Thread类,重写run方法,实例化继承类,调用start方法,即可向JVM申请开启一个线程。

java.lang.Thread::run

1
2
3
4
5
6
public void run() {
        if (this.target != null) {
            this.target.run();
        }

    }

java.lang.Thread::start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public synchronized void start() {
        if (this.threadStatus != 0) {
            throw new IllegalThreadStateException();
        } else {
            this.group.add(this);
            boolean var1 = false;

            try {
                this.start0(); //这是一个本地方法,JVM代执行。
                var1 = true;
            } finally {
                try {
                    if (!var1) {
                        this.group.threadStartFailed(this);
                    }
                } catch (Throwable var8) {
                }

            }

        }
    }

可以看到不能直接调用run方法,这样还是单线程的调用。

Runnable接口

另一种实现多线程的方法是实现Runnable接口,并使用Thread类的构造器,结合Lambda可以写成如下格式:

1
2
3
new Thread(()->{
            System.out.println("hi");
        }).start();

这种方法是更优的,因为Java中实现一个接口比继承一个类更加便于扩展。

线程属性

属性属性类型及用途只读属性注意事项
编号(ID)long,不同线程有不同的编号线程编号的唯一性只在JVM的一次运行中有效,类比Socket的连接编号
名称(Name)String,面向开发者的属性,默认值格式为”Thread-0,1,2…”×名称可以相同
线程类别(Daemon)boolean,是否为守护线程×必须在调用start之前设置,负责处理关键任务处理的不适宜设置为守护线程
优先级(Priority)int,1-10 默认为5,对于具体的某个线程,其优先级和父线程优先级相同×一般使用默认即可

Thread类常用方法

Thread.currentThread()

返回当前线程。

join()

如果线程A调用线程B的join方法,那么A的会暂停,直到线程B运行结束。

Thread.yield()

使当前线程主动放弃对其处理器的占用,可能导致当前线程被暂停

Thread.sleep()

线程暂停指定的时间。

线程关系

Java程序在启动时总是找到Main方法,JVM在这个时候会创建一个main线程,所以之后所有的线程都是main线程的子线程。

线程状态

一个线程的状态可以通过Thread.getState()来获取,该方法返回一个枚举类型:

1
2
3
4
5
6
7
8
9
10
11
public static enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;

        private State() {
        }
    }

所以以上就是线程的所有状态:

NEW

已创建但未启动。因为线程只能被启动一次,所以NEW状态只有一次。

RUNNABLE

可以被线程调度器调度或者正在运行

BLOCKED

发起阻塞式I/O或者等待其他线程占有的资源时,解除此状态会回到RUNNABLE。

WAITING

执行了某些特定方法如:Object.wait() Thread.join() LockSupport.park(Object)就会到此状态。
执行了如Object.notify()/notifyAll() LockSupport.unPark(Object) 会回到RUNNABLE状态。

TIMED_WAITING

有限的WAITING,到时间了如果其他线程没有执行该线程所期望的特定操作时,该线程会转为RUNNABLE。

TERMINATED

终止。 run正常执行或者异常而提前终止都会到该状态,仅能在该状态一次。

多线程编程的优势和风险

优势

  • 提高系统的吞吐率。
  • 提高响应性。
  • 充分利用多核。
  • 最小化系统资源使用。线程在进程内可以共享其所在进程所申请的资源。
  • 简化程序的结构。

风险

  • 线程安全。数据一致性问题。
  • 线程活性问题。死锁、活锁、线程饥饿。
  • 上下文切换。在一个线程转向另一个线程的时候叫做上下文切换,这个步骤增加了系统的消耗。
  • 可靠性。如果进程因为内存泄漏而意外终止,那么该进程中的所有线程也会终止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值