题目回顾:铁道部发布了一个售票任务,要求销售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网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算