2.进程和线程、并发和并行

本文详细介绍了Java中的进程与线程概念,包括线程的创建和状态转换。同时,讨论了并发与并行的区别,并通过代码展示了如何查看CPU核心数。此外,还深入分析了wait和sleep方法的不同点,包括它们的来源、锁的释放以及使用场景。
摘要由CSDN通过智能技术生成

在学习JUC之前,我们需要了解下进程和线程的概念,以及并发和并行的区别。

1、进程与线程:

  • 进程:一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,比如在Windows系统中,一个运行的xx.exe就是一个进程。由数据+代码+pcb(进程控制块)组成,一个进程往往至少包含一个线程
    在这里插入图片描述
  • 线程:是进程中的实际运作单位,假如我们使用qq聊天,发送信息的功能就是一个线程,也能收到信息功能也是一个线程。进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。

Tip:Java默认是拥有两个线程,main和GC(垃圾回收)线程。
对于Java而言,我么 可以使用Thread,Runnable,Callable进行创建线程。

我们思考一个问题,Java真的可以开启线程吗?

答案是不行的,我们进入Thread类查看一下源码:

/**
 * Causes this thread to begin execution; the Java Virtual Machine
 * calls the <code>run</code> method of this thread.
 * <p>
 * The result is that two threads are running concurrently: the
 * current thread (which returns from the call to the
 * <code>start</code> method) and the other thread (which executes its
 * <code>run</code> method).
 * <p>
 * It is never legal to start a thread more than once.
 * In particular, a thread may not be restarted once it has completed
 * execution.
 *
 * @exception  IllegalThreadStateException  if the thread was already
 *               started.
 * @see        #run()
 * @see        #stop()
 */
public synchronized void start() {
    /**
     * This method is not invoked for the main method thread or "system"
     * 这个方法不会被主线方法线程或“系统”调用。
     * group threads created/set up by the VM. Any new functionality added
     * 将虚拟机创建/设置的线程分组。添加的任何新功能
     * to this method in the future may have to also be added to the VM.
     *到这个方法以后可能也要添加到VM。
     * A zero status value corresponds to state "NEW".
     * 零状态值对应状态“NEW”。
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    /* Notify the group that this thread is about to be started
     *通知组该线程即将启动
     * so that it can be added to the group's list of threads
     * 以便它可以被添加到组的线程列表中
     * and the group's unstarted count can be decremented.
     * 和组的未启动计数可以减少。 */
    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
            /* do nothing. If start0 threw a Throwable then
            什么也不做。如果start0抛出一个Throwable,那么
              it will be passed up the call stack
              它将被向上传递到调用堆栈 */
        }
    }
}
//这是一个C++底层,Java是没有权限操作底层硬件的
private native void start0();

Java是没有权限去开启线程、操作硬件的,这是一个native的一个本地方法,它调用的底层的C++代码。

2、并发和并行

  • 并发:在单核的CPU中,我们要同时运行多个进程,多个程序之间的运行是交替执行的,由于切换的速度很快,从我们用户角度来看,这是一个同时进行的过程,但是微观上是交替执行的。
  • 并行:CPU多核,多个进程可以同一时刻同时执行。

我们可以通过Java查看当前计算机CPU的核心数:

public class Test {
    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}

在这里插入图片描述
线程的6种状态:

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     * 尚未启动的线程的线程状态。
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     * 可运行线程的线程状态。可运行程序中的线程
	 * 状态在Java虚拟机中执行,但它可能
	 * 等待操作系统提供的其他资源
	 * 例如处理器。
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * 等待监视器锁而阻塞的线程的线程状态。
     * 处于阻塞状态的线程正在等待监视器锁
     * 输入同步块/方法或
     * 调用后重新输入同步块/方法
     *{@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * 等待线程的线程状态。
	 * 线程由于调用其中一个线程而处于等待状态
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * 具有指定等待时间的等待线程的线程状态。
     * 线程由于调用其中一个线程而处于定时等待状态
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     * 终止线程的线程状态。
     * 线程已经完成执行。
     */
    TERMINATED;
}
线程状态
NEW(新建)线程尚未启动
RUNNABLE(运行)线程可以运行
BLOCKED(阻塞)线程阻塞
WAITING(死等)线程等待
TIMED_WAITING(过时不等)有指定时间的线程等待
TERMINATED(消亡)线程终止

wait()和sleep()的区别

1、来自于不同的类:
wait来自于Object类,而sleep属于Thread类

在企业中一般使用以下方式休眠:

//来自于import java.util.concurrent.TimeUnit包
TimeUnit.DAYS.sleep(1);	//休眠一天
TimeUnit.SECONDS.sleep(1);	//休眠一秒

在这里插入图片描述
可以根据单位的选择指定休眠的时长。

2、锁的释放:

wait方法会释放锁。

  • wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行。wait()方法可以中断线程的运行,使本线程等待,暂时让出CPU的使用权,并允许其他线程使用这个同步方法。

sleep()方法并不会释放锁。

  • 如果当前线程进入了同步锁,sleep()方法并不会释放锁。即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。

3、使用范围不同

wait:必须在同步代码块中使用
sleep:可以在任何地方使用

总结:

waitsleep
同步wait只能在同步上下文中使用,否则会抛出IllegalMonitorStateException异常sleep不用在同步代码块中调用,必须处理异常
作用对象wait方法定义在Object类中,作用于对象本身sleep属于Thread的方法,作用于当前线程
释放锁资源
唤醒条件其他线程调用notify()或者notifyAll()方法超时或者调用interrupt()方法体
方法属性wait是实例方法sleep是静态方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值