本文共 11029 字,大约阅读时间需要 36 分钟。
单核CPU
= 一个车间
:一次执行一个进程,如果执行多个程序,会在多个进程中来回切换,执行到进程里面会在多个线程之间来回切换。
多核CPU
= 一个工厂
:每次可执行多个进程;
进程
:一个车间为一个进程(一个运行的程序);进程是一种重量级的资源,系统会分配内存和CPU资源,启动和停止慢,内存相互独立
线程
:车间内一个工人为一个线程;
多线程
:一个进程包含多个线程;多个线程都可以共享一个进程的内存空间;
public class MyThread extends Thread{ @Override public void run() { for (int i = 0; i <100 ; i++) { System.out.println("hello 我是"+Thread.currentThread().getName()); } } public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start();//一个线程不能调用两次以上的start方法 IllegalThreadStateException }}
public class MyRunnable implements Runnable{ @Override public void run() { System.out.println("Runnable :"+ Thread.currentThread().getName()); } public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); //匿名内部类写法 new Thread(new Runnable() { @Override public void run() { System.out.println("匿名内部类"+Thread.currentThread().getName()); } }).start(); //lambda表达式写法 new Thread(() ->{ System.out.println("lambda:"+Thread.currentThread().getName()); }).start(); }}
public class MyCallable implements Callable{//需指定返回值类型 @Override public Long call() throws Exception { return 1+1L; } public static void main(String[] args) { //创建MyCallable对象 MyCallable myCallable = new MyCallable(); //创建FutureTask对象 FutureTask futureTask = new FutureTask<>(myCallable); //创建线程对象 Thread thread = new Thread(futureTask); thread.start(); try { System.out.println("获得结果:"+futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
Thread.sleep(毫秒)
setDaemon(true)
setPriority(int)
设置优先级,默认是5,可设置范围1~10[图片上传失败…(image-f8805d-1600949547611)]
同步方法
public synchronized 返回类型 方法名(参数){}
StringBuffer
与StringBuilder
的区别ArrayList
和Vector
的区别HashMap
和Hashtable
的区别同步代码块
public 返回类型 方法名(参数){... synchronized(锁对象){ 代码 } ...}
同步锁
java.util.concurrent
包中ReadLock
、WriteLock
、ReadWriteLock
ReentrantLock
重入锁Lock lock = new RentrantLock()
lock.lock()
上锁、lock.unlock()
释放锁lock.lock();try{ 代码}finally{ lock.unlock();}
单例模式主要分位饿汉式和懒汉式,作用是保证一个类只有一个实例对象
饿汉式
getInstance()
是否被调用,内存资源都会被消耗掉public class Singleton01 { private static Singleton01 instance = new Singleton01(); private Singleton01(){ } private static Singleton01 getInstance(){ return instance; }}
懒汉式
getInstance()
被调用时候创建对象,内存一开始不消耗getInstance()
方法中判断对象是否为null)//普通懒汉式public class Singleton02 { private static Singleton02 instance ; private Singleton02(){ } private static Singleton02 getInstance(){ if (instance == null){ instance = new Singleton02(); } return instance; }}
//双检锁懒汉式public class Singleton06 { private static Singleton06 instance ; private Singleton06(){ } private static Singleton06 getInstance(){ if (instance == null){ synchronized (Singleton06.class){ if (instance == null){ instance = new Singleton06(); } } } return instance; }}
volatile
修饰volatile
修饰public class LockTest { private static Object lock1 = new Object(); private static Object lock2 = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(() -> { for (int i = 0; i < 100; i++) { synchronized (lock1){ synchronized (lock2){ System.out.println("thread1------------"+i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); Thread thread2 = new Thread(()->{ for (int i = 0; i < 100; i++) { synchronized (lock2){ synchronized (lock1){ System.out.println("thread2------------"+i); } } } }); thread1.start(); thread2.start(); }}
通过锁对象的调用,定义在Object类中
等待wait
:让线程进入阻塞状态
wait()
:一直等待,直到被通知wait(毫秒)
:等待指定时长,线程可以被通知或自动唤醒通知notify
:让等待状态的线程从阻塞状态恢复到就绪状态
notify()
:通知一个等待线程notifyAll()
:通知所有等待线程注意,只有锁对象才能调用notify或者wait方法,必须在同步代码块的锁对象或同步方法的this调用。否则会出现IllegalMonitorStateException
异常
不是GOF23设计模式之一,是与线程相关的设计模式
作用:
实现过程:
BlockingQueue<T>
父接口LinkedBlockingQueue
链表结构的阻塞队列 (插入删除效率高)ArrayBlockingQueue
数组结构的阻塞队列(查询效率高)put()
添加数据到末尾,如果达到上线,就阻塞当前线程take()
从队列头删除数据,如果为空,就阻塞Executor
接口
execute(Runnable)
执行单个线程任务ExecutorService
接口
showdown
:关闭shutdownNow
:立刻关闭submit
:提交ThreadPoolExecutor
线程实现类
Executors
工具类
帮助创建不同类型的线程池
主要方法:
ExecutorService newCachedThreadPool()
长度不限的线程,不能控制并发量,速度更快//长度不限线程池public static void testCachedThreadPool(){ ExecutorService threadPool = Executors.newCachedThreadPool();//长度不限的线程池 for (int i = 0; i < 10; i++) { threadPool.execute(()->{ System.out.println("当前执行的是"+Thread.currentThread().getName()); }); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } threadPool.shutdown();}
ExecutorService newFixedThreadPool(int)
长度固定的线程池,可以控制并发量,并发量大时,需要排队//长度固定线程池public static void testFixedThreadPool(){ ExecutorService threadPool = Executors.newFixedThreadPool(5);//长度不限的线程池 for (int i = 0; i < 10; i++) { threadPool.execute(()->{ System.out.println("当前执行的是"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }); } threadPool.shutdown();}
ExecutorService newSingleThreadExecutor()
单线程线程池//单线程线程池public static void testSingleThreadPool(){ ExecutorService threadPool = Executors.newSingleThreadExecutor();//长度不限的线程池 for (int i = 0; i < 10; i++) { threadPool.execute(()->{ System.out.println("当前执行的是"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }); } threadPool.shutdown();}
ScheduledExecutorService newScheduledThreadPool(int)
可调度的线程池,执行线程时,可以设置执行周期和延时public static void testScheduleThreadPool(){ ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10); threadPool.scheduleAtFixedRate(()->{ System.out.println("当前执行的是"+Thread.currentThread().getName()); },5,1, TimeUnit.SECONDS); //threadPool.scheduleWithFixedDelay()}
自定义线程池
ThreadPoolExector
corePoolSize
maximumPoolSize
keepAliveTime
timeUnit
workingQueue
cpu
核心数相关, 核心数 * N (N >= 1) N具体看任务量、执行时间等情况LinkedBlockingQueue
,添加和删除任务效率高public static void myselfThreadPool(){ int processors = Runtime.getRuntime().availableProcessors(); System.out.println(processors); int n = 2; ThreadPoolExecutor threadPool = new ThreadPoolExecutor(processors * n, processors * n, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue()); for (int i = 0; i < 10; i++) { threadPool.execute(()->{ System.out.println("当前执行的是"+Thread.currentThread().getName()); }); } threadPool.shutdown(); }
threadLocal.remove()
,目的是为了避免内存泄漏转载地址:http://ouqub.baihongyu.com/