引用
先看一个程序
package Thread;
import java.util.LinkedList;
import java.util.List;
public abstract class Workquery
{
private final List<Object> query=new LinkedList<Object>();
private boolean stopped=false;
protected Workquery()
{
System.out.println("workquery。。。。。。。。。。 ");
new workThread().start();
}
public final void enquery(Object item)
{
synchronized(query)
{
query.add(item);
query.notify();
}
}
public final void stop()
{
stopped=true;
query.notify();
}
public abstract void processItem(Object item);
class workThread extends Thread
{
public void run()
{
System.out.println("work thread is running");
while (true)
{
synchronized(query)
{
while(query.isEmpty()&&!stopped)
{
try
{
System.out.println("workThread i s wait....");
query.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stopped)
{
return;
}
System.out.println("运行中...");
}Object workitem=query.remove(0);
processItem(workitem);//当这句也在同步块中时,
}
}
}
}
需要个子类的实现重写proceessItem运行
public class DeadLock extends Workquery
{
public final void processItem(final Object item)
{
Thread child =new Thread()
{
public void run()
{
enquery(item);
}
};
child.start();
try
{
child.join();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String []args)
{
new DeadLock().processItem("2");
}
}
在看程序之前需要知道
死锁的条件
引用
发生死锁的四个必要条件!
1、互斥:也许线程会用到很多资源,但其中至少要有一项是不能共享的。
2、至少要有一个进程会在占用一项资源的同时还在等另一项正被其它进程所占用的资源。
3、(调度系统或其他进程)不能从进程里抢资源。所有进程都必须正常的释放资源。
4、必需要有等待的环。一个进程在一个已经被另一进程抢占了的资源,而那个进程又在等另一个被第三个进程抢占了的资源,以此类推,直到有个进程正在等被第一个进程抢占了的资源,这样就形成了瘫痪性的阻塞了。
只要满足上面的条件就有可能发生死锁的情况~所以避免上面任何一条就可以解决多线程的死琐
那么看这个程序
首先
new DeadLock().processItem("2")
会调用父类的构造函数!假设在一个包内!!
workTread线程处于等待状态!!这时child线程启动!并且enquery一个Item这时唤醒workTread!这时child释放query锁对象!
执行到
Object workitem=query.remove(0);
processItem(workitem);
这时又启动了一个线程child这时他需要获得query的写入锁!而这时workTread还在持有锁!!还没正常释放资源!!
这样造成了死锁!!
怎么解决呢
改下workThread
processItem(workitem);
移到synchronize同步块外面!!
就可以了
了解下synchronize关键字
引用
synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。
2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
因为如果上面的程序中 在同步块中吗,那么他会防止多个程序访问query这个区块!
所以放到外面就可以了!!
有没有注意在Child.start()后有个join 这个是等待线程执行完毕后!!
http://lz12366.iteye.com/blog/640480
这里有个例子帮之理解
class workThread extends Thread
{
public void run()
{
System.out.println("work thread is running");
while (true)
{
synchronized(query)
{
while(query.isEmpty()&&!stopped)
{
try
{
System.out.println("workThread i s wait....");
query.wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stopped)
{
return;
}
System.out.println("运行中...");
}
Object workitem=query.remove(0);
processItem(workitem);//当这句也在同步块中时,
}
}
}
分享到:
相关推荐
使用并发集合(如ConcurrentHashMap)、避免过多同步块,或者使用并发工具类(如ExecutorService)可以改善并发性能。 8. **延迟初始化**:对于不经常使用的对象,可以使用懒加载策略,只在需要时才初始化。 9. **...
- 程序优化包括减少内存消耗、合理使用数据结构、避免过多同步、及时释放资源等。 8. **浮点型变量赋值**: - 浮点型变量赋值直接使用浮点常量可能导致精度丢失。应使用强制类型转换,如`float f = (float)3.4`。...
开发者可以通过使用异步请求或将耗时的请求操作放入setTimeout等JavaScript定时器中来避免同步请求带来的阻塞问题。这样可以保证用户界面的流畅性,即使在处理耗时的网络请求时也能提供良好的用户体验。
5. **后台运行优化**:在不影响用户浏览体验的前提下,适时进行后台同步,避免占用过多系统资源。 6. **安全保护**:确保在同步过程中,用户数据的加密和安全传输,保护用户隐私。 安装并启用ChromeSyncHelper-v...
- 延迟同步:对于不频繁变更的大字段,可以设置为延迟同步,避免每次更新都同步整个大字段。 - 压缩传输:在传输前对大字段进行压缩,减少网络负载,提高同步速度。 - 批量处理:批量处理大字段的更新,降低...
异步操作可以避免程序在等待某些长时间操作完成时(比如数据库操作、文件操作或者网络请求)停止执行,从而提高程序的效率。但是,过多的嵌套回调函数(回调地狱)会使得代码难以阅读和维护。 Node.js提供了一些...
- 合理使用`synchronized`,过多的同步可能导致性能下降。 - 避免死锁:当两个或更多线程互相等待对方释放资源时,会导致所有线程都无法继续执行。 - 考虑使用高级并发工具,如`ReentrantLock`、`Semaphore`等,...
此外,为了确保数据安全,用户在设置自动同步时应谨慎考虑同步策略,比如选择仅在WiFi连接下同步大文件,避免在移动网络下消耗过多流量。对于敏感数据,可能还需要加密存储,防止数据泄露。 总之,“wince 系统同步...
因此,即使在C语言编程中,也必须采取措施来避免这种情况,比如使用自旋锁、信号量或者特定于平台的同步原语。 接着,我们来看看Windows互斥量(Mutex)如何解决这个问题。互斥量是一种同步对象,允许只有一个线程...
总之,MFC提供的同步类和同步访问类极大地简化了多线程编程中的同步问题,使得开发者能够更专注于业务逻辑,而无需过多关注底层同步细节。通过选择合适的同步机制,可以有效地管理多线程程序中的资源访问,确保程序...
1. **安装与卸载**:用户可以通过同步软件在电脑上直接对手机进行软件安装和卸载操作,避免在小屏幕上手动操作的不便,尤其适合处理大量的应用管理任务。 2. **备份与恢复**:同步软件支持应用程序的备份,如果手机...
例如,系统可能为了防止恶意文件的上传而限制了某些扩展名,或者为了避免过大的文件占用过多存储空间而设定了文件大小上限。智能同步系统补丁通过识别并调整这些限制,允许用户在保证系统安全的同时,享受更广泛的...
E树Internet网络时间同步软件可以作为一个有效的替代方案,通过持续与网络时间服务器同步,避免因电池问题造成的时间混乱。 5. 时间服务器选择:软件通常会连接到多个国际认可的时间服务器,确保获取最准确的时间源...
同时,考虑到内存使用,避免一次性加载过多歌词数据。 7. **异常处理**:考虑到可能出现的网络问题、文件格式错误等情况,需要编写相应的错误处理代码,确保即使在异常情况下也能提供良好的用户体验。 在实际项目...
同时,过多的进程同步操作可能带来效率下降,应通过编程技巧优化,例如减少P、V操作次数、引入条件变量等。 5. PV操作的应用场景 PV操作在实际的操作系统设计和应用开发中有广泛的应用。例如,在多个任务协调执行、...
在iOS开发中,线程管理是一项至关重要的技能,它...在实际开发中,还需要注意合理平衡线程数量,过多的线程会消耗大量系统资源,影响应用性能。总之,熟练掌握iOS线程管理和同步技术,是每个iOS开发者必备的技能之一。
这样既可以充分利用多核处理器的计算能力,又避免了过多的并发导致的问题。 总结来说,`QSemaphore`是QT中实现线程同步和资源控制的重要工具,通过合理地使用它可以有效避免资源竞争,提高程序的稳定性和效率。配合...
通过使用信号量`S`、`C`和`MUTEX`,以及整型变量`SM`,我们可以确保理发师与顾客之间的同步,避免顾客过多导致的等待和理发师的闲置。 5. **棋子取放问题** 棋子取放问题演示了如何使用信号量`SJ`和`SY`来协调甲...
天机文件备份同步专家(FileSafe)是一种具有先进理念的文件备份同步工具,它可以实现各种你所需要的文件备份方式.帮你避免因为硬盘损坏而造成的大量数据丢失;或帮你自动保存你工作过程中所做项目或文档的每一个版本....