多线程问题及处理
2012-09-04 16:26
274 查看
多线程问题及处理
多线编程为程序开发带来了很多的便利,但也带来了一些问题。这些问题是在开发过程中中必须进行处理的。
这些问题的核心是,如果多个线程同时访问一个资源,如变量、文字等,如何保证访问安全?在多线编程中,这种会被多个线程同时访问的资源较临界资源。
一、为什么需要“线程同步”?
1、线程间共享代码和数据可以节省系统开销,提高程序运行效率,但同时也导致了数据的“访问冲突”问题,如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的“线程同步”(Synchronization)就变得至关重要。
2、Synchronization关键字是一个修饰符,可以修饰方法或代码块。其作用是:对于同一个对象(不是一个类的不同对象),当多个线程都同时调用该方法或代码块,必须依次执行,也就是说,如果两个或两个以上的线程同时执行该代码,如果一个线程已经开始执行该段代码,则另一个线程必须等待这个线程执行完这段代码才能开始执行。
3、synchronized关键字的使用方式有两种:
(1)用在对象前面限制一段代码的执行(同步代码块)
public void push(char c){
…
sychronized(this){
data[index]=c;
index++
}
}
(2)用在方法声明中,表示整个方法为同步方法:
public sychronized void show(){}
实例:
package com.hbsi;
public class TestSaleTicket {
/**
* @param args
*/
public static void main(String[] args) {
Tickets t=new Tickets();
TicketThread t1=new TicketThread(t,"张三");
TicketThread t2=new TicketThread(t,"李四");
}
}
class Tickets{
public int ticket;
public Tickets(){
ticket=10;
}
public synchronized void action(String name){
System.out.println(name+"买到了第"+ticket+"号票");
ticket--;
}
}
class TicketThread extends Thread{
Tickets t;
String name;
public TicketThread(Tickets t,String name){
this.t=t;
this.name=name;
start();
}
public void run(){
for(int i=0;i<5;i++){
t.action(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二、死锁
两个线程A、B用到同一个对象s(s为共享资源),且线程A在执行中要用到B运行后所创造的条件。在这种前提下A先开始运行,进入同步块后,对象s被锁定,接着线程A因等待B运行结束而进入阻塞状态,于是B开始运行,但因无法访问对象s,线程B也进入阻塞状态,等待s被线程A解锁。最终的结果:两个线程互相等待,都无法运行。
三、单例
如果一个类始终只能创建一个实例,则这个类被称为单例类。
分两种
1、懒汉式
class Single{
//使用一个变量来缓存创建的实例
private static Single s=null;
//将构造方法用private修饰,隐藏其构造方法
private Single(){}
//提供一个静态方法,用于返回Single实例
//该方法可以加入自定义的控制,保证只产生一个Single对象
public static Single getInstance(){
if(s==null)
synchronized(Singel.class){
if(s==null)
s=new Single();
}
return s;
}
class Single{
private static Single s=null;
private Single(){}
public static synchronized Single getInstance(){
if(s==null)
s=new Single();
return s;
}
Single.getInstance();
2、饿汉式
class Single{
private static Single s=new Single();
private Single(){}
public static Single getInstance(){
return s;
}
}
多线编程为程序开发带来了很多的便利,但也带来了一些问题。这些问题是在开发过程中中必须进行处理的。
这些问题的核心是,如果多个线程同时访问一个资源,如变量、文字等,如何保证访问安全?在多线编程中,这种会被多个线程同时访问的资源较临界资源。
一、为什么需要“线程同步”?
1、线程间共享代码和数据可以节省系统开销,提高程序运行效率,但同时也导致了数据的“访问冲突”问题,如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的“线程同步”(Synchronization)就变得至关重要。
2、Synchronization关键字是一个修饰符,可以修饰方法或代码块。其作用是:对于同一个对象(不是一个类的不同对象),当多个线程都同时调用该方法或代码块,必须依次执行,也就是说,如果两个或两个以上的线程同时执行该代码,如果一个线程已经开始执行该段代码,则另一个线程必须等待这个线程执行完这段代码才能开始执行。
3、synchronized关键字的使用方式有两种:
(1)用在对象前面限制一段代码的执行(同步代码块)
public void push(char c){
…
sychronized(this){
data[index]=c;
index++
}
}
(2)用在方法声明中,表示整个方法为同步方法:
public sychronized void show(){}
实例:
package com.hbsi;
public class TestSaleTicket {
/**
* @param args
*/
public static void main(String[] args) {
Tickets t=new Tickets();
TicketThread t1=new TicketThread(t,"张三");
TicketThread t2=new TicketThread(t,"李四");
}
}
class Tickets{
public int ticket;
public Tickets(){
ticket=10;
}
public synchronized void action(String name){
System.out.println(name+"买到了第"+ticket+"号票");
ticket--;
}
}
class TicketThread extends Thread{
Tickets t;
String name;
public TicketThread(Tickets t,String name){
this.t=t;
this.name=name;
start();
}
public void run(){
for(int i=0;i<5;i++){
t.action(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二、死锁
两个线程A、B用到同一个对象s(s为共享资源),且线程A在执行中要用到B运行后所创造的条件。在这种前提下A先开始运行,进入同步块后,对象s被锁定,接着线程A因等待B运行结束而进入阻塞状态,于是B开始运行,但因无法访问对象s,线程B也进入阻塞状态,等待s被线程A解锁。最终的结果:两个线程互相等待,都无法运行。
三、单例
如果一个类始终只能创建一个实例,则这个类被称为单例类。
分两种
1、懒汉式
class Single{
//使用一个变量来缓存创建的实例
private static Single s=null;
//将构造方法用private修饰,隐藏其构造方法
private Single(){}
//提供一个静态方法,用于返回Single实例
//该方法可以加入自定义的控制,保证只产生一个Single对象
public static Single getInstance(){
if(s==null)
synchronized(Singel.class){
if(s==null)
s=new Single();
}
return s;
}
class Single{
private static Single s=null;
private Single(){}
public static synchronized Single getInstance(){
if(s==null)
s=new Single();
return s;
}
Single.getInstance();
2、饿汉式
class Single{
private static Single s=new Single();
private Single(){}
public static Single getInstance(){
return s;
}
}
相关文章推荐
- 在vs10中处理多线程MFC遇到的问题
- JAVA多线程的问题以及处理(二)【转】
- 转 ::android多线程及异步问题 android异步处理 android多线程问题 android异步问题 android多线程处理
- Java编程那些事儿99——多线程问题及处理2
- GOOD单例模式,多线程同时访问一个实例对象问题的处理,加lock
- C# 多线程问题处理小结
- Android多线程操作sqlite(Sqlite解决database locked问题)(2)使用事务处理的效果
- Java编程那些事儿98——多线程问题及处理1
- Java编程那些事儿100——多线程问题及处理3
- 多线程问题及处理
- [原创]MFC中的多线程处理问题总结
- 多线程处理与效率问题
- CURL多线程处理需要注意问题
- winform 利用 多线程 处理窗体假死,利用 Invoke BeginInvoke 处理子线程调用 UI 控件报错的问题
- JAVA多线程的问题以及处理【转】
- C#多线程处理webbrowser及InvokeMember(click)无响应的问题
- JAVA多线程的问题以及处理
- 多线程问题的思路与处理方式。
- Java多线程(八):锁对象Lock-同步问题更完美的处理方式