首页 > 代码库 > 多线程问题的思路与处理方式。

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

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


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


加锁,只是为了让一个线程能够把操作共享数据的语句连续执行完。保证完整性。

加锁的两种方式:同步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

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