您的位置:首页 > 其它

多线程问题的思路与处理方式。

2014-09-09 11:48 197 查看
多线程问题的思路与处理方式。

一般:我们把共享资源拿出来,,把各种对共享资源操作的方法与资源封装在一起,在写方法的时候,我们就要考虑到完整性和顺序性。

加锁,只是为了让一个线程能够把操作共享数据的语句连续执行完。保证完整性。
加锁的两种方式:同步synchronized Lock lock=new ReetrentLock();
如果涉及到顺序问题,在锁里边,借助资源的flag,使用用wait,notify或者await singnal。

总之,一想到多线程,就把操作的共享资源与操作共享资源的方法封装成一个类,对操作共享数据的方法加锁。
如果多线程涉及到顺序问题,就要在(方法)锁里边操作(await,singnal,,,)。保证顺序。

下边是详细的叙述:

多个线程,,功能相同,就像卖票一样,Thread(一样)
这个时候的安全问题:是线程对共享数据操作的不完整性。
对操作共享数据的语句加锁,保证线程操作数据的完整性。
这种情况只要一把锁。
class Count
{
private int sum;
public synchronized void add(int n)
{
sum=sum+n;
try{Thread.sleep(10);}catch(Exception e){}
System.out.println("sum"+sum);
}
}

class Person implements Runnable
{
private Count b=new Count();
public void run()
{
for(int x=0;x<3;x++)
{
b.add(100);
}
}
}
class CountDemo
{
public static void main(String[] args)
{
Person p=new Person();
Thread t1=new Thread(p);
Thread t2=new Thread(p);
t1.start();
t2.start();
}
}

多个线程功能不同(执行的代码不一样),但还是在操作共享数据。
一般,把这些操作操作共享数据的语句封装成方法,与共享数据形成一个类。

1.对不同线程操作共享数据的顺序无要求:::对各个线程的执行代码加同一个锁。保证对共享数据操作的完整性。

2.对不同线程操作共享数据的顺序有要求:::使用标记(这个标记定义在资源中,共享)
只有两个线程(一对一):if
class Res
{
private String name;
private String sex;
private boolean flag=false;

public synchronized void set(String name,String sex)
{
if(flag)
{
try{this.wait();}catch(Exception e){}
}
this.name=name;
this.sex=sex;
flag=true;
this.notify();
}
public synchronized void out(int i)
{
if(!flag)
{
try{this.wait();}catch(Exception e){}
}
System.out.println(i+" "+name+".........."+sex);
flag=false;
this.notify();
}
}

3.有顺序要求。多对多。while(flag)
class Resource
{
private String name;
private int count=1;
private boolean flag=false;

private Lock lock=new ReentrantLock();
private Condition condition_pro=lock.newCondition();
private Condition condition_con=lock.newCondition();
public void set(String name) throws Exception
{
lock.lock();
try
{
while(flag)
condition_pro.await();
this.name=name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag=true;
condition_con.signal();
}
finally
{
lock.unlock();
}
}

public void out() throws Exception
{
lock.lock();
try
{
while(!flag)
condition_con.await();
System.out.println(Thread.currentThread().getName()+"......消费者......"+this.name);
flag=false;
condition_pro.signal();
}
finally
{
lock.unlock();
}
}

}

线程池:线程运行的时候,内存中会建立一个线程池。等待线程都存在线程池当中。notify唤醒线程池中的第一个线程。
线程wait后,就会进入线程池。

本文出自 “厚积薄发” 博客,请务必保留此出处http://duanzhenyue.blog.51cto.com/9360091/1550141
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: