飞道的博客

多线程(一)

411人阅读  评论(0)

进程与线程

线程是进程的一部分,线程本身不会单独存在。进程是操作系统资源分配的基本单位,线程则是资源分配的最小单位。

线程存在的意义在于提升CPU的运行效率。一个CPU单位时间只能执行一个任务,假如这个任务执行过程中阻塞,那CPU资源就被闲置。因此加入线程,在JVM层面每个线程拥有自己的虚拟机栈与程序计数器。多核CPU下,CPU执行中线程可以被挂起,根据线程的程序计数器又能从上次执行到的地方继续执行。

线程状态

操作系统进程五态

新建状态NEW:进程被创建时所处的状态。

就绪状态READY:进程已经具备了可执行条件,等待CPU调度。

运行状态Running:进程占用CPU正在执行。

阻塞状态Blocked:进程受到通信或同步操作影响,不得不放弃CPU使用。

终止状态Terminated:进程运行结束或出现严重错误。收回占用资源。

就绪-》运行:CPU分配给某个就绪的进程。

运行-》阻塞:正在运行中的进程需要等待某些事件的发生。

运行-》就绪:CPU分配的时间耗尽或其他优先级更高的进程插队

java线程状态

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.
         */
        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:还未调用start()的线程处于NEW状态。

RUNABLE: 包含了处于就绪Ready和运行Running

WAITING、TIMED_WAITING只是加入了超时时间。

线程创建

有三种创建线程的方式:实现Runable接口、继承Thread类、实现Callable

callable可以拿到线程执行的结果

public class Call implements Callable {

    @Override
    public Object call() throws Exception {
        return "test";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask futureTask = new FutureTask(new Call());
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
    }
}

线程通知机制

Object类是所有类的父类,它拥有wait()、notify()等方法。

要先使用这些方法,首先必须要拿到该对象的监视器锁(在synchronized修饰的代码块中)。

wait():线程挂起,并释放对象的监视器锁。加入锁对象的等待队列。

notify():随机唤醒一个该对象等待队列中的线程,使之进入同步队列去争抢监视器锁。notify并不会释放锁

public static void main(String[] args) throws InterruptedException {
        Object o = new Object();
         Thread threadA = new Thread(new Runnable() {
             @Override
             public void run() {

                 for (int i = 0;i<50 ;i++){
                    synchronized (o){
                     System.out.println(Thread.currentThread().getName()+"线程一"+i);
                         o.notify();
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
             }
         }});

         Thread threadB = new Thread(new Runnable() {
             @Override
             public void run() {

                 for(int j = 0; j<50 ;j++){
                     synchronized (o){
                     System.out.println(Thread.currentThread().getName()+"线程二"+j);

                         o.notify();
                         try {
                             o.wait();
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }
                     }
             }
         }});

         threadA.start();
         Thread.sleep(100);
         threadB.start();
    }

threadA先启动,之后主线程谁100ms,确保线程A先拿到对象o的监视器锁。线程A输出后,调用notify()唤醒处于等待队列的线程,此时并没又唤醒任何线程,然后wait()阻塞。此后,主线程睡眠结束,线程B开始执行。线程B输出后,执行notify()将线程A从等待队列唤醒进入同步队列,然后线程Bwait()释放锁,让线程A执行。

threadA先启动,之后主线程谁100ms,确保线程A先拿到对象o的监视器锁。线程A输出后,调用notify()唤醒处于等待队列的线程,此时并没又唤醒任何线程,然后wait()阻塞。此后,主线程睡眠结束,线程B开始执行。线程B输出后,执行notify()将线程A从等待队列唤醒进入同步队列,然后线程Bwait()释放锁,让线程A执行。

sleep()释放同步锁。


转载:https://blog.csdn.net/qq_40365331/article/details/106180547
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场