Java多线程学习总结
来源:互联网 发布:程序员月薪5万 编辑:程序博客网 时间:2024/06/05 22:59
Java多线程学习总结
- 线程的概念
- 线程的创建
- 线程的操作
- 多线程(对象锁、信号、控制)
1.线程的概念
讨论线程我们需要明白四个概念:
线程:CPU进行资源调度的最小单位,与进程中其他线程共享资源;
多线程:指的是这个程序(一个进程)运行时产生了不止一个线程;
并行:同一时刻同时执行;
并发:通过cpu调度算法,表现为一段时间上的一起执行;
1.1.线程的状态
新建状态(new)
就绪状态(Runnable)
运行状态(Running)
阻塞状态(Blocked)
死亡状态(Dead)
2.线程的创建
Java中线程的创建主要分为三种方式:常见的两种为继承Thread类、实现Runnable接口,除此之外,使用ExecutorService、Callable、Future实现有返回结果的多线程(线程池相关知识);
2.1.继承Thread类
通过继承Thread类,重新实现run函数,完成线程的创建
public class TestThread extends Thread{ @Override public void run(){ while(true){ TestUnit.print(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
2.2.实现Runnable接口
任何一个类实现了Runnable接口都可以看成线程的执行单元,可以通过Thread对象或线程池对象来完成对其的控制;
Thread t1 = new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub while(true){ TestUnit.print(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }});
2.3.使用ExecutorService、Callable、Future实现
实现Callable接口的call方法后,可作为线程池(ExecutorService)的执行单元,注册执行;Future用于获取call方法执行结果;
//TestCallable.javapackage com.aaron.concurrent.test;import java.util.concurrent.Callable;public class TestCallable implements Callable<Object> { private int taskNum = -1; public TestCallable(int i) { this.taskNum = i; } public TestCallable() { // TODO Auto-generated constructor stub } @Override public Object call() throws Exception { if(this.taskNum != -1){ return "My number is : "+ this.taskNum; } else{ return " I have no number!"; } }}//MainCallable.javapackage com.aaron.concurrent.test;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;public class MainCallable { public static final int TASK_NUM = 5; public static final int MAX_TIME_OUT = 2; public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(TASK_NUM); List<Future> returnList = new ArrayList<Future>(); for (int i = 0; i < TASK_NUM; i++) { Callable c = new TestCallable(i); Future f = pool.submit(c); returnList.add(f); } // 关闭线程池 ,等待线程执行完毕 pool.awaitTermination(MAX_TIME_OUT, TimeUnit.SECONDS); pool.shutdown(); for (Future f : returnList) { // 从Future对象上获取任务的返回值,并输出到控制台 System.out.println(f.get().toString()); } }}
3.线程的操作
3.1.启动线程:start()
start() 方法来启动线程,线程进入就绪状态,并不是马上执行run函数中的代码;
3.2.等待线程执行结束:join()
在代码中调用ThreadA.join(),会等待ThreadA执行完毕后才会执行join之后的代码
3.2.等待线程执行结束:join()
在代码中调用ThreadA.join(),会等待ThreadA执行完毕后才会执行join之后的代码
3.3.暂停:休眠(sleep)和等待(wait)
sleep和wait方法都能是线程进入阻塞状态,不过还是有不同之处,sleep方法不会交出线程的同步锁(monitor),依然参加时间片的轮转,只是不执行sleep以后的代码,同时sleep属于静态方法,只对调用它的线程有效,如Thread.sleep(100);而wait方法会释放同步锁,线程进入等待池中,不占用cpu,只用等到执行notify操作,才会唤醒该线程进入就绪状态;
3.3.让步:yield
yield函数使得线程放弃cpu使用权,从运行状态进入就绪状态,由系统进行重新调度,在实际使用中可能会没有效果,如只有一个线程;
3.4.唤醒:nitify和notifyAll
nitify函数可以唤醒正在共享对象等待池中处于阻塞状态的线程,重新进入到就绪队列,nitifyAll则是唤醒所有的阻塞线程;如果等待池中线程为空或者依旧无法获取到同步锁,则没有效果;
3.5.伪中断:interrupt
interrupt()函数只会修改线程运行的状态,并不会直接关闭线程;并通过异常的方式,提供程序员处理线程关闭的后续工作;如果线程本身处于阻塞状态(sleep/join/wait、io)会直接抛出InterruptedException 异常;否则,除非主动检查线程运行状态,interrupt()将不会有效果,也不会抛出异常;
4. 多线程(对象锁、信号、控制)
4.1.关键字(synchronized)
synchronized关键字有三个关键的问题:
1.哪里能使用
2.锁住的内容
3.锁住的对象
Java多线程同步Synchronized使用分析
4.2.锁机制(Lock接口)
synchronized关键字锁的获取和释放由硬件底层来完成,简单却不灵活,而Java提供的一些锁机制由程序员来来控制,比synchronized要灵活很多;
可以说锁是各种读写控制策略的抽象,程序员可以了解并使用Java提供的读写锁,但是也能根据具体的场景扩展读写规则;
常用的Java读写锁:重入锁(ReentrantLock)、ReentrantReadWriteLock(读写锁)
//--Lock接口public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition();}//--ReadWriteLock接口public interface ReadWriteLock { /** * Returns the lock used for reading. * * @return the lock used for reading */ Lock readLock(); /** * Returns the lock used for writing. * * @return the lock used for writing */ Lock writeLock();}
锁相关的概念(和锁机制有关):可重入锁、可中断锁、公平锁、读写锁
java多线程和并发 by人生设计师
4.3.多线程相关概念
4.3.1.死锁
锁没有释放或者同时请求同一个资源,解决一般的思路是锁的资源尽可能少,对资源的访问尽量是有序的;
4.3.1.线程安全和线程安全的集合类
当多个线程访问一个对象,如果不考虑这些线程在运行时环境下的调度和交替执行,也不需要额外的同步,或者调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的;
Java提供一些常用的线程安全集合类(java.util.concurrent包):ConcurrentHashMap、ConcurrentLinkedDeque、CopyOnWriteArrayList、StringBuffer;
- java多线程学习总结
- java多线程学习总结
- Java多线程学习总结
- java多线程学习总结
- java 多线程学习总结
- java多线程学习总结
- Java学习总结--多线程
- java多线程学习总结
- java多线程-学习总结
- Java多线程学习总结
- Java多线程学习总结
- java多线程学习总结
- java多线程学习总结
- Java多线程-学习总结
- java学习--java多线程总结
- java学习之--多线程总结
- java多线程学习与总结
- 【Java多线程】的学习总结
- JDE 发布(打包分发)流程
- java访问者模式
- jquery实现淡入淡出
- 百度地图坑汇总
- MVC、MVVM之我见
- Java多线程学习总结
- 【独家】“几维安全”获宽带资本Pre-A轮融资,在移动安全上另辟蹊径
- AS3 event flow 事件冒泡机制
- Echarts +SpringMvc 从后台数据库以json返回数据
- IDEA破解和简单用法
- mvvc
- python版本差异
- js确定删除
- 被同事要求帮修电脑时怎么拒绝最好?