`
fly_ever
  • 浏览: 150182 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

1,线程的状态转换:

新建,可运行,运行中,阻塞(等待锁),等待(不确定的等待和指定时间的等待),结束。

 

 

线程的join方法和yield方法;

join方法:

线程A中调用线程B的join方法,则线程A将会等待线程B运行结束之后再继续运行。

 

yield方法:

线程调用yield方法,则是让当前正在运行的线程,把CPU时间片让给相同优先级的其他线程去运行。

 

 

interrupt是一个实例方法,设置当前线程的中断标识位。

线程t 在sleep时,t.interrupt()被调用,会抛出InterruptedException;

线程t正在运行时,t.interrupt()被调用,isInterrupted方法会返回true,否则返回false。

isInterrupted是一个实例方法,测试的线程对象是否中断,该方法不会修改中断标志位。

interrupted 是一个静态方法,通过Thread.interrupted调用,判断当前的线程是否中断。(当前线程是指调用this.interrupt()方法的线程)。并且线程的中断状态由该方法清除,即连续调用两次该方法,则第二次会返回false。

让Main线程产生中断效果:

Thread.currentThread().interrupt();

 

System.out.println("Main thread Interrupted:" +Thread.interrupted()); 此时输出 Main thread Interrupted:true

2,Synchronized,Wait 和Notify/NotifyAll:

wait(),notify()和notifyAll()方法是Java.lang.Object类所拥有的。

Wait 和Notify/NotifyAll 必须存在于Synchronized同步块中,否则报错java.lang.IllegalMonitorStateException。

一个线程一旦调用了任意对象的wait()方法,就进入非运行状态,当同一个对象的notify()或者notifyAll()方法被调用,如果调用notify(),只唤醒一个线程,如果调用notifyAll(),该对象上调用wait()方法的全部线程都被唤醒醒。wait和nofity/notifyAll的配对使用,一定要synchronized同一个对象。

由于调用wait和notify都需要获取对象锁,因此调用wait方法后,会自动释放对象锁,之后该对象上的notify方法才能正常被执行。

被唤醒的线程如果要继续执行,也需要重新获取对象锁;调用notify方法的线程也不会立即退出,而是等待执行完synchronized代码块。

不要在字符串常量或全局对象上调用wait方法。字符串常量可能被使用在多个不同的地方。

 

3,线程的创建:

Runnable: 使用Runnable的实例创建线程,线程调用start启动,则自动开始执行run方法,不返回线程执行结果,不能抛出异常。

Callable:泛型参数化接口,通过ExecutorService的sumbit方法,启动call方法来执行,返回Future。因此能返回执行结果,能抛出异常。

ExecutorService支持创建Runnable接口和Callable接口的线程池。

 

Callable线程,通过返回Future获取结果的过程:

 

ExecutorService e = Executors.newFixedThreadPool(5);

CallBackTestThread ca = new CallBackTestThread("Producer Thread " + 21,demo);

Future<String> f = e.submit(ca);

 e.submit->AbstractExecutorService.submit(Callable<T> task) ->RunnableFuture<T> (RunnableFuture<T> ftask = newTaskFor(task);) ->new FutureTask<T>(task)

 

FutureTask实现了Runnable接口,通过传入task,建立一个FutureTask线程,然后通过execute(fTask),添加进线程池。

submit方法即完成了,1:把接口Callable实现的实例task转换位Runnable接口的实例,2,通过execute添加进线程池。

 

AbstractExecutorService类:
public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

 FutureTask同时实现了Future接口。作为Future对象,最后等线程执行完毕作为结果返回。

 

FutureTask的run方法中,直接调用Callable.call()方法,得到结果。

FutureTask保存task运行的状态:

        Possible state transitions:

     * NEW -> COMPLETING -> NORMAL

     * NEW -> COMPLETING -> EXCEPTIONAL

     * NEW -> CANCELLED

     * NEW -> INTERRUPTING -> INTERRUPTED

通过task运行的状态判断是否运行完毕,只有运行的状态是COMPLETING以及大于COMPLETING,才会返回结果,否则阻塞等待。

    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;
public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

 

总结:Callable线程是如何通过获取到Future结果的:返回的Future对象,也是一个Runnable线程,而该线程,是通过包装Callable线程来完成的,实质上运行的run()是直接调用Callable.call()来完成的。而call()会有返回值。

 

4,ThreadLocal的使用

ThreadLocal能保存线程的独立变量,ThreadLocal为每个使用该变量的线程保存一份独立的变量副本,所以每个线程都能独立的修改变量,而不会担心影响到其他的线程。

提供get(),set(T)和remove()方法。

ThreadLocal的实现是使用ThreadLocalMap来保存数据的,而使用ThreadLocal对象本身作为Key。

使用ThreadLocal的注意事项:ThreadLocal的生命周期,与线程一致。而线程池中的线程,是可以不断复用的,因此可能导致包含的ThreadLocal值一直不被释放。

 

5,线程的优先级:

Java的线程优先级范围是1-10,默认是5。10代表最高优先级,1代表最低优先级

多核多线程的平台下,线程的优先级设定,并不能保证线程完全按照优先级来执行。

yield方法只能保证给同优先级的线程提供运行的机会,没有同优先级的线程在等待运行,则yield方法直接忽略。

6,信号量Semaphore:

Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可

acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。

release()用来释放许可。注意,在释放许可之前,必须先获获得许可。

tryAcquire() :不会阻塞,会立即返回结果。获取成功,返回True,否则返回False。

Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

 

7,CountDownLunch和CyclicBarrier:

CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行。同时CyclicBarrier的值重置,以便下次使用。

如:

CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new NoticeThread());

在线程中,执行cyclicBarrier.await(); 则开始等待,等所有线程都达到这个点,则一起开始重新运行。

CyclicBarrier初始化时,还可以传入一个Runnable类,等条件到达,会自动调用该类。

await(timeout, unit),await方法也可直接传入一个时间和单位,在等待指定时间后,如果CyclicBarrier还

未达到条件,也可让该线程继续往下执行。

 

 

CountDownLunch是在某个线程完成操作后,执行计数器减1。等计数器减到0,则可以继续往下操作。

CountDownLatch countDownLatch = new CountDownLatch(5);

执行时通过countDownLatch.countDown(),让计数器减一

countDownLatch.await();则是阻塞等待计数器到达0.

 

CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的

 

0
0
分享到:
评论

相关推荐

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程编程技术

    《Java多线程编程核心技术》建议猿友们读两遍,因为其写得没有那么抽象,第一遍有些概念不是很理解,可以先跳过并记录起来,第一遍阅读的目的主要是了解整个架构。第二遍再慢慢品味,并贯穿全部是指点来思考,并将...

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程并发

    java多线程并发的在新窗口

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

    java多线程模拟队列实现排队叫号

    java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号

Global site tag (gtag.js) - Google Analytics