第1个回答 2015-06-20
第一步是让线程同步,第二部是让线程有顺序。
同步:我们可以用synchronized来解决。
java线程同步原理: java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占有权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。
当线程退出同步方法调用时,该线程会释放monitor,这将允许其他等待的线程获得monitor以使对同步方法的调用执行下去。就像下面这样:
public void test() {
synchronized (this) {
//做一些事
//这里只会有一个线程来调用该方法,因为只有一个this对象作为资源分配给该线程
}
}
顺序:我们可以用List来解决,因为它是有序的。我们只需要将要执行的线程放入到List中不就好解决了吗
上代码:
/**
* 让多个线程同步顺序执行的线程管理器
* @author bianrx
* @date 2012.1.18
* SynchronizedRunMultiThread
*/
public class SyncManager {
/**
* 待执行的线程集合,注意这里必须是Runnable接口类型,下面会解释
*/
private List<Runnable> runnableList;
public SyncManager(){}
public SyncManager(List<Runnable> runnableList) {
this.runnableList = runnableList;
}
public void setRunnable(List<Runnable> runnableList) {
this.runnableList = runnableList;
}
public void run() {
//遍历代执行的线程集合
for(Runnable runnable: runnableList) {
runThread(runnable);
}
}
/**
* 按顺序同步执行多个线程
* @author bianrx
* @date 2012.1.18
* @param runnable
*/
private void runThread(Runnable runnable) {
synchronized (this) {
runnable.run();//这里需要注意的是:必须调用run方法,因为如果你调用了start方法,线程只会向JVM请求资源,但是未必就执行其中的run。
//这个方法是同步的,所以当前只有一个线程占用了this对象。
}
}
}
测试代码:有两个要执行的线程
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("运行线程1");
}
}
public class Thread2 extends Thread {
@Override
public void run() {
System.out.println("运行线程2");
}
}
//主函数测试
public class MainTest {
/**
* @param args
* @throws ParseException
* @throws InterruptedException
*/
public static void main(String[] args) throws ParseException, InterruptedException {
List<Runnable> runnableList = new ArrayList<Runnable>();
runnableList.add(new Thread1());
runnableList.add(new Thread2());
while(true) {
Thread.sleep(1000);
new SyncManager(runnableList).run();
System.out.println("---------------");
}
第2个回答 2013-06-17
如果是A B 是两个单独的方法,没有任何关联 那么基本上是没法实现的..
除非你还有一个工具类 来控制调用类X中的A B方法,那么同步就要加在这个工具类中了
如果是A方法中调用B 那么就在调用B的地方 加一个同步代码块 Synchronized(this){调用B } 可以保证每次只有一个线程访问 调用B 处的代码
第3个回答 2013-06-17
用 sychronized 修饰方法
第4个回答 推荐于2018-05-14
1.用 synchronized 修饰方法
解决方案1:
public static void method0()
{
synchronized(类名.class)
{ //需要被同步的代码
}
}
同一个类中的所有synchronized修饰的方法是不能同时调用的,也就是说同时只能调用其中一个方法,比如线程1调用A方法,在A方法执行完之前,线程2调用B方法,这个时候线程2就会阻塞,直到线程1调用完A方法后,线程2才开始执行B方法!
2.加一个同步对象锁
就是加一个同步对象锁
public class O
{
Object lock,在A方法执行完之前,线程2才开始执行B方法;
public void A()
{
synchronized(lock)
{
/:
public class O
{
public synchronized void A(){}
public synchronized void B(){}
}
同一个类中的所有synchronized修饰的方法是不能同时调用的;这里写方法内容
}
}
public void B()
{}
synchronized(lock)
{}
/,线程2调用B方法,比如线程1调用A方法,也就是说同时只能调用其中一个方法,这个时候线程2就会阻塞;/,直到线程1调用完A方法后;/用 synchronized 修饰方法。
java多线程中.同步代码块和同步函数的区别:
同步代码块一般更好,只是同步函数,作用范围大,效率低下.同步代码块效率高些,但是要求你将可能并发出syn{},写起来比同步函数稍微难写点.本回答被网友采纳