并发的重排序疑问

“只要在某个线程中无法检测到重排序情况(即使在其他线程中可以明显地看到该线程中的重排序),那么就无法确保线程中的操作将按照程序中指定的顺序来执行”,这句话是并发编程实战里面的,我的理解是:既然都无法检测到重排序了,那线程的操作应该是按照程序中指定的顺序来执行吧。
大神来解惑一下,对并发并不是很了解,刚接触!

阅读 2.9k
1 个回答

我给你举个例子来理解多线程:

你是公司老大,你手下分别由A(架构)/B(开发)/C(测试)/D(美工)四个角色。
你现在命令A去设计架构。
B去执行开发。
C去进行测试。
D去设计UI。
你在下达以上命令后就没你什么事了,这个时候相当于:

new Thread(new Runnable() {
            
            @Override
            public void run() {
                //做事
            }
        }).start();

你的命令从各个角色的角度来看就是start,即,做本职的工作。
而各线程间可能会出现资源的竞争和制约,也就导致了各个线程的执行是在start前不可预料的。

比如测试需要等待开发完成,架构和开发之间协调资源等。

这就像:

ConcurrentHashMap<String, String> cache = new ConcurrentHashMap<>();
synchronized (cache) {
    //同一时间只能有一个线程占用我
}
new Thread(new Runnable() {
            
            @Override
            public void run() {
                cache.put("A", "A");
            }
        }).start();
new Thread(new Runnable() {
            
            @Override
            public void run() {
                cache.put("B", "B");
            }
        }).start();

当然也可以进行线程间的顺序控制,比如,只有开发B和美工D同时完成工作后测试C才开始工作。

public class CountDownLatchDemo {  
    final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    public static void main(String[] args) throws InterruptedException {  
        CountDownLatch latch=new CountDownLatch(2);//两个工人的协作  
        Worker worker1=new Worker("B", 5000, latch);  
        Worker worker2=new Worker("D", 8000, latch);  
        worker1.start();//  
        worker2.start();//  
        latch.await();//等待所有工人完成工作  
        System.out.println("B&D work done at "+sdf.format(new Date()));  
        System.out.println("now C can perform test");
    }  
      
      
    static class Worker extends Thread{  
        String workerName;   
        int workTime;  
        CountDownLatch latch;  
        public Worker(String workerName ,int workTime ,CountDownLatch latch){  
             this.workerName=workerName;  
             this.workTime=workTime;  
             this.latch=latch;  
        }  
        public void run(){  
            System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));  
            doWork();//工作了  
            System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));  
            latch.countDown();//工人完成工作,计数器减一  
  
        }  
          
        private void doWork(){  
            try {  
                Thread.sleep(workTime);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
       
}  
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题