java多线程_并发问题的解析
来源:互联网 发布:微信支付源码 编辑:程序博客网 时间:2024/06/05 07:35
首先看一下java中的多线程
1.多线程是合理充分利用了CPU,内存资源 。
2.多个线程同步操作一个加锁对象,效率是得不到提升的,记得在一个博客上看的一篇日志,将一个加锁的对象比喻成一个卫生间,同一个时间卫生间只容纳一个人,也就是一个进程对此持有对象。那么别的人只有在外面等着,此时的多进程显得是无力的。
Java中实现多线程有两种方式,一种是继承类Thread,另外一个是实现接口Runnable.无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例
首先看一个最简单的事例来简单的说一下java中线程的使用
1.继承Thread类
public class ThreadDemo extends Thread { //使用继承Thread类的方法来创建线程类时,多个线程之间无法共享线程类的实例变量 private int i=10; public void run(){ while(i>0){ System.out.println(this.getName()+"值为:"+i--); } } public static void main(String[] args) { new ThreadDemo().start(); new ThreadDemo().start(); }}
输出结果如下:
Thread-0值为:10
Thread-0值为:9
Thread-0值为:8
Thread-0值为:7
Thread-0值为:6
Thread-0值为:5
Thread-0值为:4
Thread-0值为:3
Thread-0值为:2
Thread-0值为:1
Thread-1值为:10
Thread-1值为:9
Thread-1值为:8
Thread-1值为:7
Thread-1值为:6
Thread-1值为:5
Thread-1值为:4
Thread-1值为:3
Thread-1值为:2
Thread-1值为:1
2.实现Runnable接口
public class RunnableDemo implements Runnable { private int i=10; @Override public void run() { // TODO Auto-generated method stub while(i>0){ System.out.println(Thread.currentThread().getName()+"值为:"+i--); } } public static void main(String[] args) { RunnableDemo runnableDemo=new RunnableDemo(); new Thread(runnableDemo, "A").start(); new Thread(runnableDemo, "B").start(); }}
输出结果如下:
A值为:10
B值为:9
A值为:8
A值为:6
A值为:5
A值为:4
B值为:7
A值为:3
B值为:2
A值为:1
根据以上的两个事例可以看出继承类无法实现多线程对类中定义变量的引用。
下面写一个老生常谈的示例:刚接触java的时候写的是一个火车票售票的事例,下面先来写一个事例来引入同步(synchronized)的概念
车票的实体类:
public class Tickets { private int totalTicket; public Tickets(int totalTicket) { super(); this.totalTicket = totalTicket; } public Tickets() { super(); // TODO Auto-generated constructor stub } /** * 获取 #{bare_field_comment} * @return totalTicket */ public int getTotalTicket() { return totalTicket; } /** * 设置 #{bare_field_comment} * @param totalTicket #{bare_field_comment} */ public void setTotalTicket(int totalTicket) { this.totalTicket = totalTicket; }}
进程类
public class SaleInfo extends Thread { private int getticketInfo; private Tickets tickets; private String name; public void run(){ if (tickets.getTotalTicket()>=getticketInfo) { System.out.println("可以取票"+getticketInfo); tickets.setTotalTicket(tickets.getTotalTicket()-getticketInfo); System.out.println("此时剩余的票是:"+tickets.getTotalTicket()); }else { System.out.println("余票不足"); } } public SaleInfo(String name,Tickets tickets,int getticketInfo){ this.name=name; this.tickets=tickets; this.getticketInfo=getticketInfo; }}
测试类
public class MainDemo { public static void main(String[] args) { // TODO Auto-generated method stub Tickets tickets=new Tickets(100); new SaleInfo("A", tickets, 60).start(); new SaleInfo("B", tickets, 60).start(); } }
结果如下:
可以取票60
可以取票60
此时剩余的票是:40
此时剩余的票是:-20
可以看到明显是错误的。
那么如何解决这个同步的问题呢?
这里引入了synchronized的概念,代码修改如下:
public void run(){ synchronized (tickets) { if (tickets.getTotalTicket()>=getticketInfo) { System.out.println("可以取票"+getticketInfo); tickets.setTotalTicket(tickets.getTotalTicket()-getticketInfo); System.out.println("此时剩余的票是:"+tickets.getTotalTicket()); }else { System.out.println("余票不足"); } } }
运行结果如下:
可以取票60
此时剩余的票是:40
余票不足
看到这里想到了java中锁的机制。
下面写一个锁的示例
public class SalesInfo2 extends Thread { private int getticketInfo; private Tickets tickets; private String name; private final ReentrantLock reentrantLock=new ReentrantLock(); public SalesInfo2(String name,Tickets tickets,int getticketInfo){ this.name=name; this.tickets=tickets; this.getticketInfo=getticketInfo; } public void run(){ try { reentrantLock.lock(); if (tickets.getTotalTicket()>=getticketInfo) { System.out.println("可以取票"+getticketInfo); tickets.setTotalTicket(tickets.getTotalTicket()-getticketInfo); System.out.println("此时剩余的票是:"+tickets.getTotalTicket()); }else { System.out.println("余票不足"); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ reentrantLock.unlock(); } }}
运行结果如下:
可以取票60
余票不足
此时剩余的票是:40
这里表示的是给程序上把锁,同一 时间只能有一个售票员持有对象,当该售票员释放锁之后才可以由别的售票员来操作,这种情况下是可以保证一致性,但是也会有很多弊端。
- java多线程_并发问题的解析
- java多线程并发问题
- 解决Java多线程并发的计数器问题
- JAVA并发编程1_多线程的实现方式
- java面试题_并发与多线程
- 【java并发】一道多线程问题
- java:多线程、并发相关问题
- Java多线程并发编程:volatile关键字解析
- java 关于System.out.println的多线程并发问题
- Java面试题--多线程、并发及线程的基础问题
- JAVA高并发多线程必须懂的50个问题
- JAVA高并发多线程必须懂的50个问题
- 多线程_高并发
- Servlet的多线程并发问题
- lucene多线程并发的问题
- Servlet的多线程并发问题
- 多线程_多线程举例及并行和并发的区别
- java---多线程的并发控制
- el表达式取复杂map数组的值
- ios--dispatch_semaphore
- 用户处理命令
- Struts2系统学习笔记三
- 有符号数和无符号数间的比较
- java多线程_并发问题的解析
- xml零配置之源码下载
- Android 自定义RadioButton 实现文字上下左右方向的图片大小设置
- 常用的设计模式
- DLNA原理
- python内置函数__str__作用说明
- 什么是DRAM?
- 自动更改IP地址反爬虫封锁
- java设计模式之适配器模式