Java高并发程序设计(一)--线程的概念、状态、基本操作

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

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

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

二、线程的状态

查看Thread代码,可以看到

public enum State {
        NEW,
        
        RUNNABLE,
       
        BLOCKED,
    
        WAITING,
        
        TIMED_WAITING,

        TERMINATED;
    }

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

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

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

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

扫描二维码关注公众号,回复: 2365932 查看本文章

三、线程的基本操作

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。

猜你喜欢

转载自www.cnblogs.com/blogofjzq/p/9360719.html