java关于并发的总结之三

线程简介

线程的理解

现代操作系统调度的最小单元是线程,也加轻量级进程,在一个进程里可以创建多个线程,这些线程拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。

使用多线程的原因

  • 更多的处理器核心
  • 更快的响应时间
  • 更好的变成模型

线程优先级

现代操作系统基本采用时分的形式调度运行的线程。在java线程中,通过一个整型成员变量priority来控制优先级,对应的方法为 setPriority() ,默认优先级是5,优先级高的线程分配时间片的数量要多余优先级低的线程。

线程的状态

状态名称说明
NEW初始状态,线程被构建,但还没有调用start()方法
RUNNABLE运行状态,java线程将操作系统中的就绪和运行两个状态统称为“运行中”
BLOCKED阻塞状态,表示线程阻塞于锁
WAITING等待状态,只有当其它线程进行通知或者中断的时候,等待状态的线程才会从wait()中返回
TIME_WAITING超时等待状态,在指定时间内可以自行返回
TERMINATED终止状态,表示当前线程已经执行完毕

Daemon线程

Daemon线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。当一个java虚拟机中不存在非Daemon线程的时候,java虚拟机将会退出。一个线程如果要设置为Daemon线程,必须要在这个线程start()之前进行设置。

public class Daemon {
    public static void mian(String[] args){
        Thread thread = new Thread(new DaemonRunner(),"DaemonRunner");
        thread.setDaemon(true);     //设置为Daemon线程
        thread.start();
    }

    static class DaemonRunner implements Runnable{
        public void run(){
            try{
                Thread.sleeep(4000);
            }finally{
                System.out.println("Hello world");
            }
        }
    }
}

运行程序之后,发现并没有输出。这是因为main线程和Daemon线程都在运行,main线程结束之后,Daemon就算没有运行结束也会退出。

启动和终止线程

构造线程

线程对象在构造时需要提供线程需要的属性,如线程所属的线程组、线程优先级、是否是Daemon线程等信息。

启动线程

线程对象在初始化完成之后,调用start()方法可以启用这个线程。

线程中断

其它线程通过调用该线程的interrupt()方法对该线程进行中断操作,线程还可以通过isInterrupted()方法来判断该线程是否被中断。
注意:在抛出InterruptedException的方法(比如Thread.sleep())之前,java虚拟机会先将该线程的中断标识清除,然后抛出InterruptedException,此时调用isInterrupted()方法将会返回false。

public class Interrupted{
    static class SleepRunner implements Runnable{
        public void run(){
            while(true){
                Thread.sleep(1000);
            }
        }
    }
    static class BusyRunner implements Runnable{
        public void run(){
            while(true){}
        }
    }

    public static void main(String args[]){
        Thread sleepThread = new Thread(new SleepRunner(),"sleepThread");
        sleepThread.setDaemon(true);
        Thread busyThread = new Thread(new BusyRunner(),"busyThread");
        busyThread.setDaemon(true);
        sleepThread.start();
        busyThread.start();
        Thread.sleep(5000);
        sleepThread.interrupt();
        busyThread.interrupt();
        sleepThread.isInterrupted();    //结果为false
        busyThread。isInterrupted();    //结果为true
    }
}

线程间的通信

线程等待/通知机制

等待/通知机制是任何java对象都具备的,因为这些方法被定义在Object类上

方法名称描述
notify()通知一个在对象上等待的线程,使其从wait()方法中返回,而返回的前提是该线程获取到了对象的锁
notifyAll()通知所有等待在该对象的线程
wait()调用该方法会使线程进入WAITING状态,只有等其它线程唤醒或者该线程被中断的时候才会从wait()方法返回,需要注意的是调用wait()方法之后将会释放锁
wait(long time)等待一定的时间自动返回

等待/通知机制是指当一个线程调用了对象O的wait()方法之后,该线程进入等待状态,只有当其它线程调用notifyAll()或者notify()方法之后,该线程才会从wait()方法中返回,两个线程就通过对象O来进行交互。
调用wait()、notify()可以注意的细节:
- 使用wait()、notify()等方法之前要先对调用对象加锁
- 调用wait()方法之后,线程状态将从RUNNING变为WAITING,并将当前线程放入对象的等待队列中
- notify()和notifyAll()方法调用以后,等待线程依旧不会从wait()方法中返回,需要等notify()方法的线程释放锁之后线程才有机会从wait()放回

管道输入/输出流

和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,而传输的媒介为内存

public class Piped{
    public static void main(String[] args){
        PipeWriter out = new PipedWriter();
        PipedReader in = new PipedReader();
        //将输入流和输出流进行连接,否则在使用时会抛出IOException
        out.connect(in);
        Thread printThread = new Thread(new Print(in),"Print");
        printThread.start();
        int receive = 0;
        try{
            while(receive = System.in.read()) != -1){
                out.write(receive);
            }
        }finally{
            out.close();
        }
    }
    static class Print implements Runnable{
        private PipedReader in;
        public Print(PipedReader in){
            this.in = in;
        }
        public void run(){
            int receive = 0;
            while(receive = in.read())!= -1){
                System.out.print((char)receive);
            }catch(IOException ex){
            }
        }
    }
}

可以看到对于Piped类型的流,必须要先进行绑定,调用connect()方法将输入和输出流绑定起来。

ThreadLoacal的使用

ThreadLocal即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值
比如说线程A设置一个线程ID为A,set(A),则通过get()方法返回的就是A;线程B设置线程Id为B,则get()方法得到的就是B

有一些关于线程池和线程应用的具体代码在github上,欢迎大家指点迷津
https://github.com/WilderGao/ThreadStudy

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值