java多线程相关
1.创建线程的三种方式
1.声明线程类继承Thread类,重写run()方法,然后使用的时候,new对象调用start()方法开始线程执行。
代码实例
public class MyThread extends Thread{//继承Thread类
public void run(){
//重写run方法
} }
public class Main {
public static void main(String[] args){
new MyThread().start();//创建并启动线程
} }
2.声明线程类实现Runnable接口,重写run()方法,使用时new 对象,将其传入到new的Thread对象中,Runnable接口实际上是线程要执行的任务,所以我们还要创建一个线程对象来执行这个任务.
代码实例: public class MyThread2 implements Runnable {//实现Runnable接口
public void run(){
//重写run方法
} }
public class Main {
public static void main(String[] args){
//创建并启动线程
MyThread2 myThread=new MyThread2();
Thread thread=new Thread(myThread);
thread().start();
}
}
3.Callable接口,和Runnable类似,里边只有一个call方法,不同的是,这个方法可以报出异常,并且有返回值。但是呢,这个call方法不是人为调用的,而是执行了Thread对象的start方法自动调用了,所以要想个办法获得call方法的返回值,所以就有了Future类,它创建的时候需要一个Callable,它的get方法就可以获得这个返回值,还有个问题就是Thread只能接收Runnable接口作为参数,所以要有个接口既实现了了Future接口能获得返回值,还实现了Runnable能传给Thread,这个接口就是RunnableFuture,它的实现类是FutureTask。
new Thread(new FutureTask(new Callable()<Integer>{})<Integer>)要给出call方法返回值类型
优缺点:
Runnable方式更好,可以将任务交给不同的线程执行,实现资源共享,并且可以继承其他类。
如果需要异常处理或者执行后需要返回值那Callable更好。
2.阻塞队列:1.多线程安全。2.消费者来取队列内容时,如果队列为空,则阻塞等待。生产者来放内容时,如果队列满了,则阻塞等待。
3.线程池
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); }
corePoolSize:核心线程数,线程池自带的线程数量。
maximumPoolSize:最大线程数,当队列满了,并且当前线程数量小于最大线程数,则创建新的线程从队列中取任务执行。
keepAliveTime:当队列中没有任务时,对于核心数目的线程会保持这段时间后销毁。
unit:枚举类型,代表keepAliveTime的单位是什么。
workQueue:装任务的队列,不同队列直接决定了线程池的任务策略。
ThreadFactory:默认的,创建线程的工厂
defaultHandler:任务提交失败时执行,可以抛出异常之类的。
4.线程池的种类
FixedThreadPool :固定大小的线程池,底层还是ThreadPoolExcuter,只是设置了一些参数。核心线程数量和最大线程数量相等,传入进来,是无界队列。
CachedThreadPool:可缓存的线程池,底层还是ThreadPoolExcuter,只是设置了一些参数。核心线程数为零,最大线程数为最大值,等待时间是60s,队列是SynchronousQueue,没有存储空间,
来个任务,就创建一个线程处理。
SingleThreadExecutor :单例线程池,底层还是ThreadPoolExcuter,只是设置了一些参数,核心线程和最大线程都为1,队列是普通的LinkedBlockingQueue。
ScheduledThreadPool :可调度的线程池,实现定时或者延时执行。
// 1. 创建 定时线程池对象 & 设置线程池线程数量固定为5
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
// 2. 创建好Runnable类线程对象 & 需执行的任务
Runnable task =new Runnable(){
public void run(){
System.out.println("执行任务啦");
}
};
// 3. 向线程池提交任务:schedule()
scheduledThreadPool.schedule(task, 1, TimeUnit.SECONDS); // 延迟1s后执行任务
scheduledThreadPool.scheduleAtFixedRate(task,10,1000,TimeUnit.MILLISECONDS);// 延迟10ms后、每隔1000ms执行任务
// 4. 关闭线程池
scheduledThreadPool.shutdown();
5.CAS:在java.util.current.atomic包下面,采用了CAS机制来实现加锁,对变量使用。
CAS+volatile实现了锁的作用
sychronized:原子性、可见性、顺序性
volatile:可见性、顺序性
CAS:原子性

浙公网安备 33010602011771号