-
关于多线程通讯地一个疑问20
新手学JAVA,学到多线程,编了一个简单地电脑城进出货模拟系统。
代码有点长,主要部分如下所述:
有三方:厂家,电脑城,顾客
厂家2个,一个生产主板,一个生产显卡。
顾客有2个,他们各自不断购买主板和显卡。
电脑城有一个,卖显卡和主板。
限于篇幅问题,摘录主要代码如下:
--------------------------厂家类---------------------------------------public class Mainboardretailer implements Runnable// 主板厂家 { public void run() { while(true) { 电脑城.stockMainboard(deliverMB("MSI"));//不断向电脑城供货 } } public Mainboard deliverMB(String 主板名) { return 主板; } } public class Videocardretailer implements Runnable// 显卡厂家 { public void run() { while(true) { 电脑城.stockVideocard(deliverVC("ATI"));//不断向电脑城供货 } } public videocard deliverMB(String 显卡名) { return 显卡; } }
-------------------------------------顾客类-------------------------------------------public class customer implements Runnable { public void run() { while(true) { buyVC("ATI"); //顾客不断购买显卡和主板 buyMB("MSI"); } } }
-----------------------------电脑城类-----------------------------------------public class ComputerCenter { int MAXVCSTORE = 100;//货仓容量 int MAXMBSTORE = 100;//货仓容量 private static LinkedList<Videocard> VideocardQty = new LinkedList<Videocard>();//显卡货仓 private static LinkedList<Mainboard> MainboardQty = new LinkedList<Mainboard>();//主板货仓 public synchronized void stockVideocard(Videocard VCname) { if(VideocardQty.size() >= MAXVCSTORE) { System.out.println("ComputerCenter: the VC storage is MAX"); try { wait();//---------------------当存货过多时。通知厂商等待。 } catch (InterruptedException e) { e.printStackTrace(); } } VideocardQty.add(VCname); notify();//----------------------------唤醒消费者消费 } public synchronized void stockMainboard(Mainboard MBname) { if(MainboardQty.size() >= MAXVCSTORE) { System.out.println("ComputerCenter: the MB storage is MAX"); try { wait();//----------------------当存货过多时。通知厂商等待。 } catch (InterruptedException e) { e.printStackTrace(); } } MainboardQty.add(MBname); notify();//-----------------------------唤醒消费者消费 } public synchronized Videocard sellVideocard(String VCname) { if(VideocardQty.size() <= 0) { try { wait();//-----------------没有存货时,通知消费者等待 }catch(Exception e) { e.printStackTrace(); } } notify();//----------------------------------唤醒厂商 return MyVideocard; } public synchronized Mainboard sellMainboard(String MBname) { if(MainboardQty.size() <= 0) { try { wait();//-----------------没有存货时,通知消费者等待 }catch(Exception e) { e.printStackTrace(); } } notify();//----------------------------------唤醒厂商 return MyMainboard; } public static void main(String[] args) { ComputerCenter MyCC = new ComputerCenter(); new customer(MyCC,"Jack").start(); new customer(MyCC,"Tom").start(); new Mainboardretailer(MyCC).start(); new Videocardretailer(MyCC).start(); } }
现在出现了这样的一个问题:
1.如果有两个消费者同时等待,厂家生产后唤醒其中消费者A,消费者A购买完毕后会唤醒消费者B--不合逻辑。
2.如果购买显卡地消费者A在等待,电脑城从主板厂商进货了主板以后会唤醒消费者A。同样的情况也发生在购买主板的消费者B身上。
3.如果两家厂商在等待消费者购买商品,此时消费者A购买了主板,货仓主板数量-1,然后有可能唤醒显卡厂商而没有唤醒主板厂商进行生产。
4.如果两家厂商正在等待消费者购买商品,此时显卡厂商被唤醒后,可能立刻唤醒主板厂商生产主板,令到商品数量超出仓库上限。
我想,有没有什么办法,可以指定唤醒某个线程?如果可以,那问题就容易解决了。
问题补充:xmind 写道主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。class ComputerCenter { private static Object VIDEO = new Object(); private static Object MAINB = new Object(); private static Integer videoN = 10; private static Integer MainbN = 10; public void stockVd() { synchronized(VIDEO) { if(videoN >= 20) { System.out.println("ComputerCenter: the VC storage is MAX"); try {VIDEO.wait();} catch (Exception e) {} } System.out.println("ComputerCenter: 厂商送来一块显卡。"); videoN++; VIDEO.notify();//----------------------------唤醒消费者消费 } } public void stockMd() { synchronized(MAINB) { if(MainbN >= 20) { System.out.println("ComputerCenter: the MB storage is MAX"); try {MAINB.wait();} catch (Exception e) {} } System.out.println("ComputerCenter: 厂商送来一块主板。"); MainbN++; MAINB.notify();//-----------------------------唤醒消费者消费 } } public void sellVd(String name) { synchronized(VIDEO) { if(videoN <= 0) { System.out.println("没有显卡了,等等,马上送来!!!!!!!!!"); try {VIDEO.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块显卡。"); videoN--; VIDEO.notify();//----------------------------------唤醒厂商 } } public void sellMd(String name) { synchronized(MAINB) { if(MainbN <= 0) { System.out.println("没有主板了,等等,马上送来!!!!!!!!!!"); try {MAINB.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块主板。"); MainbN--; MAINB.notify();//----------------------------------唤醒厂商 } } public static void main(String[] args) { ComputerCenter MyCC = new ComputerCenter(); new customer(MyCC,"Jack").start(); new customer(MyCC,"Tom").start(); new Md_retailer(MyCC).start(); new Vd_retailer(MyCC).start(); } } class customer extends Thread { private ComputerCenter cc; private String name; public customer(ComputerCenter cc,String name) { this.cc = cc; this.name = name; } public void run() { while(true) { //try {Thread.sleep(10);} catch (Exception e) {} //顾客不断购买显卡和主板 cc.sellVd(name); cc.sellMd(name); } } } class Md_retailer extends Thread { private ComputerCenter cc; public Md_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockMd(); } } } class Vd_retailer extends Thread { private ComputerCenter cc; public Vd_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockVd(); } } }
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。
非常感谢您,我修改了一下代码,用synchronized代码块来指定唤醒地对象。但是依然有一个问题:当有2人同时在等待买显卡地时候,厂商送来一块显卡,A买完后,却会唤醒B去买。这里有逻辑错误。该怎么样改进一下呢?
其实还有有种办法解决,就是通过在wait()那里套一个while(iswaiting)来实现唤醒指定地线程。电脑城进货后,改变某个boolean值,唤醒所有线程。那些没有被改变boolean值的线程将被套在while循环里面。这样可以解决问题,但我总觉得怪怪地不自然。
问题补充:xmind 写道噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看public void sellMd(String name) { synchronized(MAINB) { if(MainbN <= 0) { System.out.println("没有主板了,等等,马上送来!!!!!!!!!!"); try {MAINB.wait();} catch (Exception e) {} } if(MainbN >0) { System.out.println(name + " : 买走一块主板。"+MainbN); MainbN--; } MAINB.notify();//----------------------------------唤醒厂商 } } }
谢谢您。我觉得呢,这样子看上去是可行的,但还有一点逻辑上的错误。假如A,B都在等待买显卡,此时电脑城获得一块显卡,库存显卡数为1,通知AB其中一个。假设A买到了显卡,显卡库存变为0。此时A唤醒B。B醒来后if判断显卡数不大于0,所以并没有买走显卡,但是他却被唤醒并离开了,也就是说他这次不买显卡了(他本来是想买显卡的,只不过没货,在等待)。并且他离开时通知了电脑城再进一块显卡(如果此时达到库存上线,厂商在等待消费,那么它将被B唤醒而生产显卡,导致电脑城显卡数超出库存)。
这里是不是有点逻辑上的小漏洞呢?大家探讨探讨。
问题补充:hareamao 写道
import java.util.ArrayDeque; public class StockManager { private final Object producerLock = new Object(); private final Object consumerLock = new Object(); private final int MAX_SIZE = 10; private final ArrayDeque<Product> queue = new ArrayDeque<Product>(); public void stock(Product p) throws InterruptedException { synchronized (producerLock) { if (queue.size() >= MAX_SIZE) { producerLock.wait(); } } synchronized (queue) { queue.add(p); } synchronized (consumerLock) { consumerLock.notify(); } } public synchronized Product purchase() throws InterruptedException { synchronized (consumerLock) { if (queue.size() <= 0) { consumerLock.wait(); } } Product product = null; synchronized (queue) { product = queue.remove(); } synchronized (producerLock) { producerLock.notify(); } return product; } }
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
阁下的方法是,将StockManager分开实例化令厂商解锁时只解在自己队列上排队的顾客,从而避免了唤醒另外一条队的顾客。这样子也可以。thanks。
另外问一句,为什么阁下的代码中这么多final的?
2010年7月25日 18:33
6个答案 按时间排序 按投票排序
-
采纳的答案
没怎么写过多线程,拿来练练手,未必正确。
public class Product { private String name; private int serial; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSerial() { return serial; } public void setSerial(int serial) { this.serial = serial; } }
import java.util.ArrayDeque; public class StockManager { private final Object producerLock = new Object(); private final Object consumerLock = new Object(); private final int MAX_SIZE = 10; private final ArrayDeque<Product> queue = new ArrayDeque<Product>(); public void stock(Product p) throws InterruptedException { synchronized (producerLock) { if (queue.size() >= MAX_SIZE) { producerLock.wait(); } } synchronized (queue) { queue.add(p); } synchronized (consumerLock) { consumerLock.notify(); } } public synchronized Product purchase() throws InterruptedException { synchronized (consumerLock) { if (queue.size() <= 0) { consumerLock.wait(); } } Product product = null; synchronized (queue) { product = queue.remove(); } synchronized (producerLock) { producerLock.notify(); } return product; } }
import java.util.logging.Logger; public class Producer implements Runnable{ private static final Logger log = Logger.getLogger(Producer.class.getName()); private String productName = null; private int serial = 0; private StockManager stockManager; public void setProductName(String productName) { this.productName = productName; } public void setStockManager(StockManager stockManager) { this.stockManager = stockManager; } public Product produce() { final Product p = new Product(); p.setName(productName); p.setSerial(++serial); return p; } @Override public void run() { try { for( int i = 0; i < 20; i++) { deliver(); } Thread.sleep(30 * 1000); while (true) { deliver(); } } catch (InterruptedException e) { e.printStackTrace(); } } private void deliver() throws InterruptedException { final long s = System.currentTimeMillis(); final Product product = produce(); stockManager.stock(product); final long time = System.currentTimeMillis() - s; if (time > 10) { log.info(product.getName() + ", No. " + product.getSerial() + " took " + time + " milli seconds to finish." ); } } }
import java.util.logging.Logger; public class Consumer implements Runnable { private static final Logger log = Logger.getLogger(Consumer.class.getName()); private String name; private StockManager[] stockManagers; public void setName(String name) { this.name = name; } public void setStockManagers(StockManager[] stockManagers) { this.stockManagers = stockManagers; } @Override public void run() { for (int i = 0; i < 50; i++) { final double v = Math.random() * stockManagers.length; final int k = (int) Math.floor(v); try { final long s = System.currentTimeMillis(); final Product product = stockManagers[k].purchase(); final long time = System.currentTimeMillis() - s; String l = ""; if (time > 10) { l += "after " + time + " milli seconds of waiting, "; } l += (name + " bought product " + product.getName() + ", serial No. " + product.getSerial()); log.info(l); } catch (InterruptedException e) { e.printStackTrace(); break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); break; } } } }
public class Mall { public static void main(String[] args) { final StockManager mb = new StockManager(); final Producer pmb = new Producer(); pmb.setProductName("Motherboard"); pmb.setStockManager(mb); final StockManager vd = new StockManager(); final Producer pvd = new Producer(); pvd.setProductName("Video Card"); pvd.setStockManager(vd); final StockManager[] stockManagers = new StockManager[2]; stockManagers[0] = mb; stockManagers[1] = vd; final Consumer c1 = new Consumer(); c1.setName("C1"); c1.setStockManagers(stockManagers); final Consumer c2 = new Consumer(); c2.setName("C2"); c2.setStockManagers(stockManagers); new Thread(c1).start(); new Thread(c2).start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(pmb).start(); new Thread(pvd).start(); } }
2010年7月26日 21:31
-
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
2010年7月26日 21:36
-
恩,是有点儿,这样你看行不行,也就是顾客在买的时候,如果没有等待,买完后也不通知。电脑城在进货满之后不等待(或者sleep也行,让出cpu,现实中像是卖一段时间在进货),没进一个货就通知一声,只通知一个顾客。
class ComputerCenter { private static Object VIDEO = new Object(); private static Object MAINB = new Object(); private static Integer videoN = 10; private static Integer MainbN = 10; public void stockVd() { synchronized(VIDEO) { if(videoN >= 20) { System.out.println("ComputerCenter: the VC storage is MAX"); } else { videoN++; System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN); VIDEO.notify();//----------------------------唤醒消费者消费 } } } public void stockMd() { synchronized(MAINB) { if(MainbN >= 20) { System.out.println("ComputerCenter: the MB storage is MAX"); } else { MainbN++; System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN); MAINB.notify();//-----------------------------唤醒消费者消费 } } } public void sellVd(String name) { synchronized(VIDEO) { if(videoN <= 0) { System.out.println("没有显卡了,等等,马上送来!!!!!!!!!"); try {VIDEO.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块显卡。"+videoN); videoN--; } } public void sellMd(String name) { synchronized(MAINB) { if(MainbN <= 0) { System.out.println("没有主板了,等等,马上送来!!!!!!!!!!"); try {MAINB.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块主板。"+MainbN); MainbN--; } } public static void main(String[] args) { ComputerCenter MyCC = new ComputerCenter(); new customer(MyCC,"Jack").start(); new customer(MyCC,"Tom").start(); new Md_retailer(MyCC).start(); new Vd_retailer(MyCC).start(); } } class customer extends Thread { private ComputerCenter cc; private String name; public customer(ComputerCenter cc,String name) { this.cc = cc; this.name = name; } public void run() { while(true) { //try {Thread.sleep(10);} catch (Exception e) {} //顾客不断购买显卡和主板 cc.sellVd(name); cc.sellMd(name); } } } class Md_retailer extends Thread { private ComputerCenter cc; public Md_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockMd(); } } } class Vd_retailer extends Thread { private ComputerCenter cc; public Vd_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockVd(); } } }
2010年7月26日 19:19
-
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看class ComputerCenter { private static Object VIDEO = new Object(); private static Object MAINB = new Object(); private static Integer videoN = 10; private static Integer MainbN = 10; public void stockVd() { synchronized(VIDEO) { if(videoN >= 20) { System.out.println("ComputerCenter: the VC storage is MAX"); try {VIDEO.wait();} catch (Exception e) {} } videoN++; System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN); VIDEO.notify();//----------------------------唤醒消费者消费 } } public void stockMd() { synchronized(MAINB) { if(MainbN >= 20) { System.out.println("ComputerCenter: the MB storage is MAX"); try {MAINB.wait();} catch (Exception e) {} } MainbN++; System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN); MAINB.notify();//-----------------------------唤醒消费者消费 } } public void sellVd(String name) { synchronized(VIDEO) { if(videoN <= 0) { System.out.println("没有显卡了,等等,马上送来!!!!!!!!!"); try {VIDEO.wait();} catch (Exception e) {} } if(videoN >0) { System.out.println(name + " : 买走一块显卡。"+videoN); videoN--; } VIDEO.notify();//----------------------------------唤醒厂商 } } public void sellMd(String name) { synchronized(MAINB) { if(MainbN <= 0) { System.out.println("没有主板了,等等,马上送来!!!!!!!!!!"); try {MAINB.wait();} catch (Exception e) {} } if(MainbN >0) { System.out.println(name + " : 买走一块主板。"+MainbN); MainbN--; } MAINB.notify();//----------------------------------唤醒厂商 } } public static void main(String[] args) { ComputerCenter MyCC = new ComputerCenter(); new customer(MyCC,"Jack").start(); new customer(MyCC,"Tom").start(); new Md_retailer(MyCC).start(); new Vd_retailer(MyCC).start(); } } class customer extends Thread { private ComputerCenter cc; private String name; public customer(ComputerCenter cc,String name) { this.cc = cc; this.name = name; } public void run() { while(true) { //try {Thread.sleep(10);} catch (Exception e) {} //顾客不断购买显卡和主板 cc.sellVd(name); cc.sellMd(name); } } } class Md_retailer extends Thread { private ComputerCenter cc; public Md_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockMd(); } } } class Vd_retailer extends Thread { private ComputerCenter cc; public Vd_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockVd(); } } }
2010年7月26日 17:17
-
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。class ComputerCenter { private static Object VIDEO = new Object(); private static Object MAINB = new Object(); private static Integer videoN = 10; private static Integer MainbN = 10; public void stockVd() { synchronized(VIDEO) { if(videoN >= 20) { System.out.println("ComputerCenter: the VC storage is MAX"); try {VIDEO.wait();} catch (Exception e) {} } System.out.println("ComputerCenter: 厂商送来一块显卡。"); videoN++; VIDEO.notify();//----------------------------唤醒消费者消费 } } public void stockMd() { synchronized(MAINB) { if(MainbN >= 20) { System.out.println("ComputerCenter: the MB storage is MAX"); try {MAINB.wait();} catch (Exception e) {} } System.out.println("ComputerCenter: 厂商送来一块主板。"); MainbN++; MAINB.notify();//-----------------------------唤醒消费者消费 } } public void sellVd(String name) { synchronized(VIDEO) { if(videoN <= 0) { System.out.println("没有显卡了,等等,马上送来!!!!!!!!!"); try {VIDEO.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块显卡。"); videoN--; VIDEO.notify();//----------------------------------唤醒厂商 } } public void sellMd(String name) { synchronized(MAINB) { if(MainbN <= 0) { System.out.println("没有主板了,等等,马上送来!!!!!!!!!!"); try {MAINB.wait();} catch (Exception e) {} } System.out.println(name + " : 买走一块主板。"); MainbN--; MAINB.notify();//----------------------------------唤醒厂商 } } public static void main(String[] args) { ComputerCenter MyCC = new ComputerCenter(); new customer(MyCC,"Jack").start(); new customer(MyCC,"Tom").start(); new Md_retailer(MyCC).start(); new Vd_retailer(MyCC).start(); } } class customer extends Thread { private ComputerCenter cc; private String name; public customer(ComputerCenter cc,String name) { this.cc = cc; this.name = name; } public void run() { while(true) { //try {Thread.sleep(10);} catch (Exception e) {} //顾客不断购买显卡和主板 cc.sellVd(name); cc.sellMd(name); } } } class Md_retailer extends Thread { private ComputerCenter cc; public Md_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockMd(); } } } class Vd_retailer extends Thread { private ComputerCenter cc; public Vd_retailer(ComputerCenter cc) { this.cc = cc; } public void run() { while(true) { try {Thread.sleep(10);} catch (Exception e) {} cc.stockVd(); } } }
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。2010年7月26日 11:19
-
1.消费者由生产唤醒,每次唤醒队列中的一个,A买完就走,不要多管闲事
2.不同的产品在不同的队列中,不要排别人的队
3.4.同22010年7月26日 09:08
相关推荐
在linux下用socket的多线程通讯实现一个服务器和多个客户端之间的相互通讯。如果要实现多个和多个客户端通讯,则只需将里面的thread_client编译成多个文件即可。代码绝对是能用的~有什么疑问请留言~希望对大家伙有...
多线程编程的一个重要特性是在同一JOB内可以创建多个线程,这些线程共享JOB的资源,但每个线程也有其独立的执行环境。 ###### 1.3.4 线程的私有数据和共有数据 - **私有数据**:每个线程独有的数据,不会被其他...
高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4 高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4 高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4 高...
高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4 高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4 高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4 高...
2. **多线程**:即时通讯系统需要处理并发连接,因此多线程编程是必不可少的。C#的System.Threading命名空间提供了Thread、Mutex、Semaphore等类,用于管理并发操作和同步。 3. **消息队列**:为了处理大量并发请求...
【描述】中的内容与标题一致,确认了这是一个关于Java编程的项目,主要关注点在于创建一个聊天应用程序,模拟MSN的功能。 【标签】“Java”揭示了该项目的核心技术,Java是一种广泛使用的面向对象的编程语言,以其...
这个Java聊天程序源代码展示了一个基本的客户端-服务器架构的即时通讯应用。以下是该程序涉及的关键知识点: 1. **Socket编程**: - `Socket` 类在Java中用于网络通信,它代表了客户端和服务器之间的连接。在这个...
这是一个关于使用Java编程语言开发简单聊天程序的问题。在这个程序中,包含了两个主要的文件:`XueLiangServer.java` 和 `XueLiangClient.java`,分别代表服务器端和客户端。初学者在尝试实现一个基本的即时通讯功能...
API使用的网关服务器拥有多线程发送能力,每秒可同时处理数十个客户端的并发请求。 平台无关性 客户端适用于任何可运行JAVA的平台,包括:Windows、LINUX、UNIX、MAC等。 不像DLL接口,只能运行于WINDOWS平台...
4. **时间管理**:高效率地处理多线程工作,确保快速响应客户需求。 5. **数据分析**:理解数据背后的趋势,为优化服务和提升业绩提供依据。 此外,持续的培训和发展也是培养金牌客服的关键。企业应定期进行客服...
活动文档包容是指一种技术,它允许一个文档对象作为活动对象被嵌入到另一个应用程序中。这种技术使得文档能够在不同的应用程序之间共享和交互。 #### 活动结尾 (Active End) 活动结尾通常指的是一个操作或流程的...
5. 异步处理:运用Grand Central Dispatch(GCD)进行多线程处理,提升用户体验。 四、性能优化 1. 离线缓存:对常用数据进行本地缓存,即使在网络不稳定时也能正常使用。 2. 懒加载:对于非首屏内容,采用懒加载...
实现一个IM实时聊天应用,少不了弄服务器,目前开源的Openfire服务器就比较合适,而且很多功能都已经封装好了,实现聊天APP就简洁很多。服务器后端的数据库我选择了MySQL,当然Openfire也支持大部分的主流数据库,...
有了上边的知识,开发文件传输功能就变得简单多了,文件的接受也可以类推了,同样开启一个线程维护接受文件链表,逐次接受身下的文件,链表为空时。文件传输会遇到文件读写问题,有的文件发送是被打开了,这样会...
Java-Push-Framework 是一个基于Java的开源框架,它的设计目标是为开发者提供一个高效、易用的工具,用于构建高性能的服务器应用。这个框架是Push Framework的Java实现,原版Push Framework是一个C++库,专门针对...