Java常用高级线程操作

针对Java线程操作一直不太明白,今天找了一本高级教材,有专门介绍Java7支持的线程操作,稍微记录一下各种类和使用条件

1.synchronized对象锁

使用synchronized来锁定一个对象,但是使用在类的方法中的时候会造成整个类的对象被锁,因此对于其他没有此关键字的标记也无法被其他线程操作。

synchronized可以锁定任意代码块,可以锁定任意对对象作为代码块的锁。

2.volatile进行线程同步

volatile作为一个在内存和线程之间同步变量的关键字,不会再本地保存变量的二次拷贝。

3.ReentrantLock超时锁的一个实现,可以实现锁住代码块

在此类对象的.lock()和unlock()之间的代码块是被锁定的块,其下面的方法

lock.tryLock(10, TimeUnit.SECONDS);

可以用来指定超时时间。

4.阻塞队列

这个是针对消费/生产问题的一个实现,一般使用LinkedBlockingQueue来指定具有无限容量的队列,ArrayBlockingQueue是有界的阻塞队列,

还有一个叫LinkedTransferQueue的实现,但是不是太明白书中的例子,应该是一种按需的队列,就是如果队列中有等待使用数据的线程,那么插入数据的线程一旦启动,就会产生需要的所有数据,而一旦没有等待/请求数据的线程,就不产生数据。

5.同步器

信号量Semaphore这个类是用来生成信号量的,信号量的所谓机制就是如果信号量标记有正在处理的事件的时候,所有请求都被驳回,但是如果有空闲就接受请求。

看我写的小例子:

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return new AtomicInteger(1).incrementAndGet();
            }
        };

        Semaphore semaphore = new Semaphore(4,true);

        try {
            while (true) {
                if (semaphore.tryAcquire(2, TimeUnit.SECONDS)) {
                    Future<Integer> future = executorService.submit(callable);
                    System.out.println(future.get());
                }
            }
        }catch (InterruptedException e){

        }catch (ExecutionException e){

        }finally {
            executorService.shutdown();
        }
    }
}

看到的是ExecutorService创建了10个的线程池(姑且称为线程池),但是信号量是四个,那么执行的时候只能看到四个输出;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return new AtomicInteger(1).incrementAndGet();
            }
        };

        Semaphore semaphore = new Semaphore(4,true);

        try {
            while (true) {
                if (semaphore.tryAcquire(2, TimeUnit.SECONDS)) {
                    Future<Integer> future = executorService.submit(callable);
                    System.out.println(future.get());
                }
                semaphore.release();
            }
        }catch (InterruptedException e){

        }catch (ExecutionException e){

        }finally {
            executorService.shutdown();
        }
    }
}

这段是加上了一个叫release的semaphore的方法,此方法释放一个信号量许可,并返回给semaphore。

6.屏障

作为屏障的描述:是一个节点,这个节点是一个会和点,所有操作执行完毕之后都会转到此位置,也就是说所有已经完成任务的线程都要等到其他线程完成,者有点像守护线程的概念。CyclicBarrier实现了屏障,它的构造方法指定一个数字和一个Runnable对象,数字是它调度指挥的线程的数目,Runnable是所有线程都结束之后CyclicBarrier执行的操作,

这个可以解决并行的一些算法运算,那个Runnable就是用来合并结果的(使用分治法思想)。

7.Callable,Future接口

这两个对象都是能够返回县城运行结果的,Callable是被ExecutorService来执行的,Service的submit返回一个Future对象,可以使用它的get方法返回Callable 的运行结果,但是注意只有线程运行完毕之后Future才能有值可以返回

FutureTask是一个既实现Runnable又实现了Future接口的对象,既可以用他的run方法,又可以被submit

8.Executors

这个类的一系列的静态方法来创建线程池并返回ExecutorService对象,newFixedThreadPoll是创建固定大小的线程池,newCacheThreadPool是创建60s之后自动销毁的线程池,这个方便了在小段时间时线程数变化比较大的时候可以节省时间和内存。

newSingleThreadExecutor是创建 一个可以重用的线程。

newScheduledThreadPool创建一个指定大小的线程池,不同的是这个线程池执行线程的操作时按照时序来的,可以指定延迟和次数,可以通过返回的ScheduledExecutorService对象的scheduleAtFixedRate指定一个runnable还有其首次执行的延迟和之后两次调用之间的延迟

9.ForkJoinPool和ForkJoinTask

这两个也是一个用来创建线程池的方法,但是不同的是它们执行的线程可以被合并结果,但是他们执行的任务对象就使用其抽象子类,ForkJoinTask的实现抽象子类:RecursiveTask和RecursiveAction。

前者是可以返回结果,后者是无法返回结果的。计算要实现在compare实现的方法中。执行任务之后可以调用ForkJoinPool的invoke方法来提交一个任务,还有一个名为invokeAll()的方法,但是这个方法如何使用我还不是很了解,因为这个All方法调用的 参数是一个Callable对象集合而非ForkJoinTask。

10.线程安全的随机数生成ThreadLocalRandom类

一般情况下使用它的静态方法就可以生成,比如:

ThreadLocalRandom.current().nextLong(100);

生成的是以0为下限和100的上限的随机数。

这个应当是一个线程安全的随机数生辰器,因此可以考虑在并行运算中使用它。

时间: 2024-08-07 02:18:24

Java常用高级线程操作的相关文章

Java基本的线程操作(附代码)

啦啦啦啦,从头整理一遍java并发的内容.开始是基本的线程操作 线程状态切换: 新建线程: @Test public void newTread(){ Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("ok..."); } }); t1.start(); } 终止线程: Thread.stop() 不推荐使用.它会释放所有monitor 中断线程: publ

Java常用四大线程池用法以及ThreadPoolExecutor详解

为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率 2.线程并发数量过多,抢占系统资源从而导致阻塞 3.对线程进行一些简单的管理 在Java中,线程池的概念是Executor这个接口,具体实现为ThreadPoolExecutor类,学习Java中的线程池,就可以直接学习他了对线程池的配置,就是对ThreadPoolExecutor构造函数的参数的配置 一.ThreadPoolExecutor提供了四个构造函数: //五个参数的构造函数 pu

Java常用的线程池

Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待.newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行.newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有

oracle常用高级sql操作

一.运算符 算术运算符:+ - * / 可以在select 语句中使用 连接运算符:||    select deptno|| dname from dept; 比较运算符:> >= = != < <= like between is null in 逻辑运算符:not and or 集合运算符: intersect ,union, union all, minus 要求:对应集合的列数和数据类型相同 查询中不能包含long 列 列的标签是第一个集合的标签 使用order by时,

Java 中几种常用的线程池

Java 中几种常用的线程池 转载 : https://www.cnblogs.com/sachen/p/7401959.html 原创 2016年04月14日 23:29:01 标签: java / 线程池 / Executor 878 概述: 在java内置API中操作线程所用到的类为Thread.创建线程一般有两种方式, 继承Thread方式 实现Runnable方式,并以runnable作为target创建Thread 在Android中的耗时任务一般都需要另开线程来执行,常常需要用线程

线程基础:线程(2)——JAVA中的基本线程操作(上)

文章注明来源:http://blog.csdn.net/yinwenjie,主要供自己学习转载用 1.JAVA中线程的状态 1-1.#对象锁 在Java中每一个对象都有一把‘锁’,这个‘锁’可以是开放状态:也可以由某一个线程(或者多个线程)持有‘钥匙’:一旦在系统中某个对象的‘锁’存在至少一把‘钥匙’,那么任何线程操作这个对象,都必须验证是否有‘钥匙’,如果没有则会报IllegalMonitorStateException异常. 可是‘锁芯’(对象独占权)只有一个,那么可以打开这把锁的多个‘钥匙

线程基础:线程(3)——JAVA中的基本线程操作(中)

(接上文<线程基础:线程(2)--JAVA中的基本线程操作(上)>) 1-4.注意synchronized关键字的使用 在前面的文章中我们主要讲解的是线程中"对象锁"的工作原理和操作方式.在讲解synchronized关键字的时候,我们还提到了synchronized关键字可以标注的位置.大家经常看到相当部分的网贴,在它们的代码示例中将synchronized关键字加载到代码的方法体上,然后告诉读者:这个操作是线程安全的.代码可能如下: /** * 这个类的class对象进

Java并发学习之四——操作线程的中断机制

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.如果线程实现的是由复杂算法分成的一些方法,或者他的方法有递归调用,那么我们可以用更好的机制来控制线程中断.为了这个Java提供了InterruptedException异常.当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常. 2.InterruptedException异常是由一些与并发API相关的Java方法,如sleep()抛出的. 下面以程序解释 package chapter; import java.io.File

java线程操作范例

一:线程操作范例(1) package com.cloud.day6; public class Demo1 { publicstatic void main(String[] args) { MyThreadmt1=new MyThread("线程A", 1000); MyThreadmt2=new MyThread("线程B", 2000); MyThreadmt3=new MyThread("线程C", 3000); mt1.start()