题目回顾:铁道部发布了一个售票任务,要求销售1000张票,要求有3个窗口来进行销售,请编写多线程程序来模拟这个效果。   i. 窗口001正在销售第1000张票   ii. 窗口001正在销售第999张票   iii. 窗口002正在销售第998张票   iv. …   v. 窗口002正在销售第1张票   vi. 票已经销售完毕    问题1:三个线程都卖了1000张票,一共卖了3000张票
Java售票任务_多线程详细实现
一 、注意细节:
     原因:三个线程代表三个对象,就有三个成员变量(三个ticket)
     解决方案:让成员变量ticket变成静态变量,因为静态变量是该类所有对象共享的变量
    问题2:有些票卖了重票
     原因:输出后切换到其他的线程,ticket变量没有–,所以造成了数据错误
     解决方案:加锁,保证输出和ticket–运行完毕后,才能切换到其他线程
    问题3:票数出现负数
     原因:ticket零界点,3个线程都有可能进入
     解决:在同步代码里再此判断
    synchronized 同步锁、互斥锁:
    注意:多个线程之间要想互斥,必须用同一把锁对象
    同步代码块:
    synchronized(锁对象){//上锁
        …代码…
      }//解锁
      同步方法:
    Lock锁:二、 继承Thread接口实现
2.1 第一种解决方案:同步代码块
/*synchronized 同步锁、互斥锁:  *  注意:多个线程之间要想互斥,必须用同一把锁对象    *  同步代码块:    *   synchronized(锁对象){//上锁    *    ...代码...    *   }//解锁    * / public static void main(String[] args) {   myThread01 t1 = new myThread01("窗口一");   myThread01 t2 = new myThread01("窗口二");   myThread01 t3 = new myThread01("窗口三");   t1.start();   t2.start();   t3.start();  } } class myThread01 extends Thread{  private static int tecket = 1000;  private static Object obj= new Object();  public myThread01(String name) {   super(name);  }  @Override  public void run() {   while(tecket>0){    synchronized (obj) {    if(tecket>0){    System.out.println(Thread.currentThread().getName()+"正在销售第"+tecket+"张票");    tecket--;    }else if(tecket==0){    System.out.println(Thread.currentThread().getName()+"票已卖完");    }else{    System.out.println(Thread.currentThread().getName()+"票已卖完");    }     }   }  } 2.2 第二种解决方案:同步方法
public static void main(String[] args) { /**    *  同步方法:    *   锁对象 -- this    *   public synchronized void method01(){}    *   锁对象 -- 本类的字节码文件对象    *   public synchronized static void method02(){}    */   myThread01 t1 = new myThread01("窗口一");   myThread01 t2 = new myThread01("窗口二");   myThread01 t3 = new myThread01("窗口三");   t1.start();   t2.start();   t3.start(); } } class myThread02 extends Thread{ private static int tecket = 1000; private static Object obj= new Object(); public myThread02(String name) { super(name); } @Override public void run() { while(tecket>0){ method01(); } } public synchronized static void method01(){ synchronized (obj) { if(tecket>0){   System.out.println(Thread.currentThread().getName()+"正在销售第"+tecket+"张票");   tecket--; }else if(tecket==0){   System.out.println(Thread.currentThread().getName()+"票已卖完"); }else{   System.out.println(Thread.currentThread().getName()+"票已卖完"); } } } 2.3 第三种解决方案:lock锁
 public class Thread_03 { public static void main(String[] args) {   myThread01 t1 = new myThread01("窗口一");   myThread01 t2 = new myThread01("窗口二");   myThread01 t3 = new myThread01("窗口三");   t1.start();   t2.start();   t3.start(); } } /*  * * Lock锁:  *  Lock lock = new ReentrantLock();  */ class myThread03 extends Thread{ private static int tecket = 1000; //创建lock锁对象 private static Lock lock = new ReentrantLock(); public myThread03(String name) { super(name); } @Override public void run() { while(tecket>0){    lock.lock();//上锁 if(tecket>0){    System.out.println(Thread.currentThread().getName()+"正在销售第"+tecket+"张票");    tecket--; }else if(tecket==0){    System.out.println(Thread.currentThread().getName()+"票已卖完"); }else{    System.out.println(Thread.currentThread().getName()+"票已卖完"); }     lock.unlock();//解锁 } } } 2.4 两种上锁方式对比:synchronized vs Lock(重要)
  区别1:   *   synchronized锁 会自动上锁、解锁   *   Lock锁 必须手动上锁、解锁   *  区别2:   *   synchronized JVM层面上的锁   *   Lock API层面上的锁   *  区别3:   *   Lock有读写锁 三、Runnable接口实现
3.1第一种方式实现:同步代码块
 public class Runnable_01 { public static void main(String[] args) {    myRunnable01 task = new myRunnable01();    Thread task1 = new Thread(task,"窗口一");    Thread task2 = new Thread(task,"窗口二");    Thread task3 = new Thread(task,"窗口三");    task1.start();    task2.start();    task3.start(); } } class myRunnable01 implements Runnable{ private int ticket = 1000; private Object obj = new Object(); @Override public void run() { // TODO Auto-generated method stub while(ticket > 0){ //   synchronized("abc"){ //   synchronized(Object.class){ //   synchronized(obj){ synchronized(this){ if(ticket > 0){      System.out.println(Thread.currentThread().getName() + "正在销售第" + ticket + "张票");      ticket--; if(ticket == 0){       System.out.println(Thread.currentThread().getName() + "票已卖完"); } }else{      System.out.println(Thread.currentThread().getName() + "票已卖完"); } } } } } 3.2 第二种方式实现:同步方法
p public class Runnable_02 { public static void main(String[] args) {    myRunnable02 task = new myRunnable02();    Thread task1 = new Thread(task,"窗口一");    Thread task2 = new Thread(task,"窗口二");    Thread task3 = new Thread(task,"窗口三");    task1.start();    task2.start();    task3.start(); } } class myRunnable02 implements Runnable{ private static int ticket = 1000; private Object obj = new Object(); @Override public void run() { // TODO Auto-generated method stub while(ticket > 0){ //   synchronized("abc"){ //   synchronized(Object.class){ //   synchronized(obj){ methodR01(); } } public synchronized void methodR01(){ if(ticket > 0){     System.out.println(Thread.currentThread().getName() + "正在销售第" + ticket + "张票");     ticket--; if(ticket == 0){      System.out.println(Thread.currentThread().getName() + "票已卖完"); } }else{     System.out.println(Thread.currentThread().getName() + "票已卖完"); } } } 3.3 第三种方式实现:lock锁
 public class Runnable_03 { public static void main(String[] args) {    myRunnable03 task = new myRunnable03();    Thread task1 = new Thread(task,"窗口一");    Thread task2 = new Thread(task,"窗口二");    Thread task3 = new Thread(task,"窗口三");    task1.start();    task2.start();    task3.start(); } } class myRunnable03 implements Runnable{ private int ticket = 1000; private Lock lock = new ReentrantLock(); @Override public void run() { // TODO Auto-generated method stub while(ticket > 0){ //   synchronized("abc"){ //   synchronized(Object.class){ //   synchronized(obj){    lock.lock(); if(ticket > 0){      System.out.println(Thread.currentThread().getName() + "正在销售第" + ticket + "张票");      ticket--; if(ticket == 0){       System.out.println(Thread.currentThread().getName() + "票已卖完"); } }else{      System.out.println(Thread.currentThread().getName() + "票已卖完"); }     lock.unlock(); } } } 四、附加 哲学家吃饭问题
 public class Test01 { public static void main(String[] args) { //死锁 //尽可能不要锁嵌套 //线程1 new Thread(new Runnable() { @Override public void run() { synchronized (KuaiZi.a) { try {       Thread.sleep(10); } catch (InterruptedException e) {       e.printStackTrace(); } synchronized(KuaiZi.b){       System.out.println("哲学家1 吃饭了"); } } } }).start(); //线程2 new Thread(new Runnable() { @Override public void run() { synchronized (KuaiZi.b) { try {       Thread.sleep(10); } catch (InterruptedException e) {       e.printStackTrace(); } synchronized(KuaiZi.a){       System.out.println("哲学家2 吃饭了"); } } } }).start(); } } class KuaiZi{ public static Object a = new Object(); public static Object b = new Object(); } 
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)