并发-----java多线程理解与总结
来源:互联网 发布:淘宝自动浏览软件app 编辑:程序博客网 时间:2024/06/08 11:08
------- android培训、java培训、期待与您交流! ----------
多线程Thread:一个进程中拥有多个可执行路径,一个程序至少有一个进程,而一个进程至少有一个线程;
java对多线程的支持方案:1继承Thread类,2实现Runnable方法
特点:由于线程是程序的多条执行路径,所以执行权CPU说了说,多线程具有随机性和并发性;
Thread类概述:
- run()方法概述:这个方法里封装了线程要执行的代码,也就是说我们将想要多线程执行的代码的地方,如果对象直接调用则不是多线程;
- start()方法:让线程就绪,执行run()方法体;
- 在线程就绪前,也就是start()调用前,我们可以设置线程的优先级,守护线程等,易于理解
- isLive()测试线程是否是激活状态
- interrupt(),中断线程
- thread类试图通过自己的方法来控制线程合理的在理想状态下执行,但是cpu的多核多线程技术使得他不可能理想的完成,所以,其他的方法就看api了解
- 线程的生命周期图
cpu操作是具有原子性的,所以判断线程时候存在问题的条件为:
- 是否是多线程 ,这个必须是,因为我们编写的就是多线程程序
- 是否有共享代码,从这一步就要考虑问题的存在了,因为每个线程都有自己的栈内存,程序计数器等
- 是否是同一把锁,这个往往被忽略,但是jdk5出现的显示的锁,一般这一步不会出错了;
- 是否有多条语句操作共享语句,解决问题的根本所在了
解决问题的方法:同步代码块,同步方法。前提:多线程,同一把锁
格式: 1synchronized(对象){} 2public synchronized void 方法名(){}
还是卖票吧,只不过我将飘封装称了类,稍微有点不同
1票类:
<span style="white-space:pre"></span>public class Ticket {//张数private int number;//票价private float price;public Ticket(int number) {this.number=number;}//get set省略2卖票具体线程类:
public class SaleTicke implements Runnable {private Ticket t;public SaleTicke(Ticket t) {this.t = t;}@Overridepublic void run() {//这个不是共享数据//int sx=t.getNumber(),并且用sx来判断,各自的栈内存都会有这么一个变量,所以会出现卖200张票while (true) {
<span style="white-space:pre"></span>//将所有操作的资源的语句全部用同步代码块包裹synchronized (this) {if (t.getNumber() > 0) {System.out.println(Thread.currentThread().getName()+ "出售了第" + (t.getNumber()) + "张票");//卖一张,减少一张,就这里不同t.setNumber(t.getNumber() - 1);} else {break;//run()方法结束,线程结束,jvm结束}}}}}
3卖票测试类:
<span style="white-space:pre"></span>public static void main(String[] args) {Ticket resource =new Ticket(100);SaleTicke st=new SaleTicke(resource);Thread t1=new Thread(st,"窗口-1");Thread t2=new Thread(st,"窗口-2");t1.start();t2.start();}4卖票总结:当票被封装为类时,第二种安全因素就诞生了,以及在取出值之后要调用set方法来重新设置
5线程间通信:等待唤醒机制,运用jdk5新特性,生产者,消费者
/** *资源类 */public class Resource {//资源名private String name;//数量private int count=0;//标记private boolean flag=false;//锁private Lock lock=new ReentrantLock();private Condition set=lock.newCondition();public Resource(){}//创造资源public void creatResource() throws InterruptedException{lock.lock();try {//if只判断一次,在这里用不合适while(flag)//有,等set.await();++count;System.out.println(Thread.currentThread().getName()+"-----生产第"+count+"个商品");//重置标记flag=true;//唤醒set.signal();} finally{lock.unlock();}}//消费public void useRes() throws InterruptedException{lock.lock();try {while(!flag)//没有,等set.await();System.out.println(Thread.currentThread().getName()+"正在消费第" + count + "商品");//重置标记flag=false;//唤醒set.signal();} finally{lock.unlock();}}}
/** * 生产者 */public class Creat implements Runnable{private Resource r=null;public Creat(Resource r){this.r=r;}public Creat(){}@Overridepublic void run() {while(true){try {r.creatResource();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
/** * 消费者 */public class Use implements Runnable{private Resource r = null;public Use(Resource r) {this.r = r;}public Use() {}@Overridepublic void run() {while(true){try {r.useRes();} catch (InterruptedException e) {e.printStackTrace();}}}}
/** * 测试类 */public class UseTest {public static void main(String[] args) {Resource r=new Resource();Creat c=new Creat(r);Use u=new Use(r);new Thread(c,"生产者").start();new Thread(u,"消费者").start();}}
结果:
生产者-----生产第26911个商品消费者正在消费第26911商品生产者-----生产第26912个商品消费者正在消费第26912商品生产者-----生产第26913个商品消费者正在消费第26913商品生产者-----生产第26914个商品消费者正在消费第26914商品生产者-----生产第26915个商品消费者正在消费第26915商品生产者-----生产第26916个商品消费者正在消费第26916商品生产者-----生产第26917个商品消费者正在消费第26917商品生产者-----生产第26918个商品消费者正在消费第26918商品生产者-----生产第26919个商品消费者正在消费第26919商品生产者-----生产第26920个商品消费者正在消费第26920商品
死锁:锁嵌套使用导致
public class DieLock {public static void main(String[] args) {new MyThread(true).start(); new MyThread(false).start(); }}class Lock {public static final Object lock1 = new Object();public static final Object lock2 = new Object();}class MyThread extends Thread {private boolean flag = false;MyThread(boolean b){this.flag=b;}public void run() {if (flag) {//锁1嵌套锁2synchronized (Lock.lock1) {System.out.println("锁1.....");synchronized (Lock.lock2) {System.out.println("锁12..........");}}} else {//锁2嵌套锁1synchronized (Lock.lock2) {System.out.println("锁2||||||||");synchronized (Lock.lock1) {System.out.println("锁22||||||||||||");}}}}}
总结:
1清楚的讲,多线程让我的头大了许多,非常不理解为什么会出错,调试比较难受,啊,真的炸了,最后,一步步分析,判断,找出问题出现的地方并且对症下药才可以;
2那四个判断条件是多么的重要:在写一次
- 是否是多线程 (是否同时加锁),这个必须是,因为我们编写的就是多线程程序
- 是否有共享代码,从这一步就要考虑问题的存在了,因为每个线程都有自己的栈内存,程序计数器等
- 是否是同一把锁,这个往往被忽略,但是jdk5出现的显示的锁,一般这一步不会出错了;
- 是否有多条语句操作共享语句,解决问题的根本所在了
------- android培训、java培训、期待与您交流! ----------
0 0
- 并发-----java多线程理解与总结
- java多线程与并发总结
- java并发与多线程总结
- 深入理解Java多线程与并发编程
- Java 多线程与并发编程总结
- Java 多线程与并发编程总结
- Java 多线程与并发编程总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- Java+多线程与并发编程总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结(转)
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- JAVA多线程与并发学习总结
- POJ 3276 Face The Right Way (开关问题的优化_好题)
- 黑马程序员——阿龙的学习历程——Java初见
- getRequestDispatcher 和sendRedirect区别
- maven 出现 -source 1.3中不支持泛型的错误
- docker 核心概念整理
- 并发-----java多线程理解与总结
- C++求两个日期之间的相差天数
- 在Linux下编写Daemon
- noip2011 mayan游戏 (深搜)
- 含有构造函数反射生成java类
- compileSdkVersion和targetSdkVersion的区别
- Redis 禁用FLUSHALL FLUSHDB KEYS 命令
- php使用MemCache查询数据库
- 容器类 视图控制器 页面之间的跳转