zoukankan      html  css  js  c++  java
  • Java高并发程序设计(一)--线程的概念、状态、基本操作

    一、线程的概念
    先说进程的概念:进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是线程的容器。是程序的实体。

    而线程就是轻量级的进程,是程序执行的最小单位。

    打个比方,进程是一家公司对外提供服务,线程就可以是公司里的各个部门或员工。线程各司其职,相互协作,使用公共资源等。

    二、线程的状态

    查看Thread代码,可以看到

    public enum State {
            NEW,
            
            RUNNABLE,
           
            BLOCKED,
        
            WAITING,
            
            TIMED_WAITING,
    
            TERMINATED;
        }

    源代码中列举了六个线程的状态:

    new表示线程刚刚创立还没开始执行,对应的terminated表示线程的结束

    线程执行时处于runnable,一切资源都已经准备好,当线程碰到同步代码块,进入blocked阻塞状态,线程暂停执行,直到获得锁。

    waiting和timed_waiting都是等待状态,区别是一个是有时间的等待,一个是需要特殊事件(如wait,join)的等待,完成等待后重新进入runnable

    三、线程的基本操作

    1.新建

    (1)继承Thread

    (2)重载runnable

    2.终止

    Thread.stop(),不推荐使用,stop是直接停止,释放所有锁,可能造成数据不一致的情况

    3.中断

    线程中断不会使线程退出,而是告诉线程有人希望你退出,具体退出由线程自己决定

    Thread.interrupted(); //判断有没有中断并清除当前中断状态
    Thread.isInterrupted();//判断有没有中断
    Thread.interrupt(); //中断
    public static void main(String[] args) throws InterruptedException
        {
            Thread t=new Thread(){
                @Override
                public void run()
                {
                    while(true)
                    {
                        System.out.println("run");
                                       if(Thread.currentThread().isInterrupted())
                        {
                            System.out.println("over");
                            break;
                        }
                    }
                }
            };
            t.start();
            Thread.sleep(100);
            t.interrupt();
        }

    在上面的例子里线程是永久运行的直到得到中断标志

    另外,Thread.sleep()会抛出InterruptedException中断异常,当在睡眠时被中断。值得注意的是异常抛出后会清理中断状态

    4.等待和通知

    notify() notifyAll() wait() 不属于Thread类,属于Object类。一般在synchronize中使用。

    当在一个对象上使用wait()时,线程就会在对象上等待,notify随机唤醒一个在对象上等待的线程,notifyAll唤醒所有。

    wait方法前必须获得对象的监视器,wait之后释放监视器,这里和sleep不同。

    public class threadDemo {
        static Object obj=new Object();
        class waitThread extends Thread{
            @Override
            public void run()
            {
                synchronized(obj)
                {
                    System.out.println(System.currentTimeMillis()+"w start");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(System.currentTimeMillis()+"w end");
                }
            }
        }
        class notifyThread extends Thread{
            @Override
            public void run()
            {
                synchronized(obj)
                {
                    System.out.println(System.currentTimeMillis()+"n start");
                    obj.notifyAll();
                    System.out.println(System.currentTimeMillis()+"n end");
                }
            }
        }
        public static void main(String[] args) throws InterruptedException
        {
            waitThread w=new threadDemo().new waitThread();
            notifyThread n=new threadDemo().new notifyThread();
            w.start();
            Thread.sleep(1000);
            n.start();
        }
    }

    5.挂起和继续执行

    suspend() resume() 已废弃,不推荐使用

    6.等待结束和谦让

    join() yeild()

    有时候一个线程的输入需要依赖另一个线程的输出,这时候就需要线程的顺序执行,join()就可以实现顺序执行

    public static int i=0;
        class waitThread extends Thread{
            @Override
            public void run()
            {
                for(i=0;i<1000;i++){}
            }
        }
        public static void main(String[] args) throws InterruptedException
        {
            waitThread w=new threadDemo().new waitThread();
            w.start();
            w.join();
            System.out.println(i);
        }

    这里主线程等待w线程执行完才输出i的值为1000,如果没有join的话,i值几乎不可能是1000。

    join的本质还是用wait和notify使调用线程等着在现在线程的实例上。

    yeild()让当前线程让出cup。

  • 相关阅读:
    叙旧
    注册表的基本操作(.Net)
    如何自己实现 JavaScript 的 new 操作符?
    装饰者模式和TypeScript装饰器
    彻底弄懂GMT、UTC、时区和夏令时
    Javascript 中 cookie 操作方式
    javascript实例教程:使用canvas技术模仿echarts柱状图
    实现memcached客户端:TCP、连接池、一致性哈希、自定义协议
    Linux终端快速检测网站是否宕机的6个方法
    爬虫是什么吗?你知道爬虫的爬取流程吗?
  • 原文地址:https://www.cnblogs.com/blogofjzq/p/9360719.html
Copyright © 2011-2022 走看看