线程互斥问题,程序执行的流程

问题描述

线程互斥问题,程序执行的流程
 public class TT implements Runnable {
    int b = 100;

    public synchronized void m1() throws Exception{
        b = 1000;
        Thread.sleep(5000);
        System.out.println("b = " + b);
    }

    public synchronized void m2() throws Exception {
        Thread.sleep(2500);        //在在这里睡一下跟不睡结果不同,怎么会呢?
        b = 2000;
    }

    public void run() {
        try {
            m1();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        TT tt = new TT();
        Thread t = new Thread(tt);
        t.start();

        tt.m2();
        System.out.println(tt.b);
    }
}

如上代码段,运行结果为:
1000
b=1000
如果将注释的那一行代码去掉,运行结果为:
2000
b=1000
为什么会这样啊?不是在主线程main中运行到t.start()重新另启动一个线程,但是主线程还在运行,到tt.m2()先获得互斥锁,睡眠2.5秒,修改b=2000,然后主线程立即执行打印2000,然后t.start()才获得互斥锁,执行b=1000。有没有sleep不是都一样的么?求高手指点?

解决方案

我们把两种情况都分析一下:
第一种m2中有Thread.sleep(2500):
t.start()启动子线程,会直接调用run()->m1()。而在m1()中,b=1000;然后开始延时Thread.sleep(5000);
另一方面,主线程继续执行tt.m2()。而在m2()中开始延时Thread.sleep(2500);之后才会b=2000;
主线程继续System.out.println(tt.b);输出b的值(此时b=1000,m1()和m2()都在延时中)
(这里有点不明白的是tt.m2()和System.out.println(tt.b)的执行顺序,tt.m2()如果是在主线程中运行这里b的值理应为2000.)

第二种m2中没有延时:
前面一样,但tt.m2()是就直接b=2000了;
主线程继续System.out.println(tt.b);输出b的值(此时b等于1000还是2000就看m1()和m2()的执行顺序了)

解决方案二:

BioUsb-程序执行流程分析

解决方案三:

并不是这个sleep()的原因。原因可能是:你的主线程启动好新线程之后直接就运行m2了,而新线程的启动不是马上就完成的,所以由于主线程运行比较快,你看的是一个类似永远确定的结果。

你可以把m2()里的sleep改的很小试试看,不如50ms之类的。多运行几次你应该会发现两个线程其实是在相互竞争的。

解决方案四:

m1(),{m2(),System.out.println(tt.b);}这两个函数的执行顺序不确定,就看谁先执行了,你sleep的时间很长,就隐含着给它们加了顺序

解决方案五:

sleep的时间改小一些就能看到不同

解决方案六:

使用线程,一般需要给临界变量加线程互斥锁啊

解决方案七:

第一种情况m1()先于m2()执行,System.out.println(tt.b)在m1() sleep期间执行(延时够长可以这么确定)
第二种情况则相反,且System.out.println(tt.b)先于m1()执行,也只有这样才能解释的通了。
至于为什么两种情况下m1()和m2()执行顺序不一样只能说这是个不确定因素吧。

时间: 2024-12-03 09:22:25

线程互斥问题,程序执行的流程的相关文章

关于信号量与线程互斥锁的区别与实现

  http://dev.firnow.com/course/6_system/linux/Linuxjs/20090901/173322.html 之前一直没有怎么关注过这个问题,前些日子在面试一家公司的时候,面试官提到了pthread_cond_wait/pthread_cond_signal的实现,当时答的不是很好,回来就查了nptl的代码.前天,水木上又有人问到了信号量和互斥锁的问题,我想还是对它们的区别与实现总结一下. 首先了解一些信号量和线程互斥锁的语义上的区别: >>>&g

php程序的三大流程控制

php程序的三大流程控制 ① 顺序控制(从上到下,从左到右) ②分支控制 if(条件表达式){ //n多语句 }else if (条件表达式){ //n 多语句 }else if(条件表示式){ //. }//这里可能还有更多的else if else{   } u switch分支语句 基本语法结构 switch(表达式){ case 常量1: //n多语句; break; case 常量2: //n多语句 break; default: //n多语句; break; } u 常量的类型 (i

delphi线程问题 delphi 程序里我写了一个方法

问题描述 delphi线程问题 delphi 程序里我写了一个方法 delphi 程序里我写了一个方法,方法里面的算法比较复杂,计算起来时间比较长,我想把这个方法单独放到一个线程里去执行,请问是怎么写?一点头绪没有啊,谢谢 解决方案 unit Unit1; interface uses Windows Messages SysUtils Variants Classes Graphics Controls Forms Dialogs StdCtrls; type TForm1 = class(T

代码-linux应用程序的运行流程 求详解

问题描述 linux应用程序的运行流程 求详解 事情是这样的,老师给了个作业(如下),因为课程时间等原因,开始想要啃下2.6源码的,在各种深度了解,剖析 巴拉巴拉等的linux电子书里并没有看出多大的头绪,讲到看源码更是头大,加之时间有限,所以并没有时间去仔细的研读,想要请各位大神给些指导,毕竟看到操作系统的庞大代码就不知道从哪里入手了. 如果有耐心+时间的话 更希望能够给出一些具体的解题入手步骤,如:怎么去跟踪程序的函数运行,函数间调用大概关系是怎么研究... 请不要嫌弃...知识掌握有限,想

进度条 线程中断-进度条执行一次后,线程没有中断,第二次点击鼠标事件时不更新

问题描述 进度条执行一次后,线程没有中断,第二次点击鼠标事件时不更新 我是设定boolean来中断线程,执行一次进度条后二次点击鼠标事件时不再更新且弹出的搜索条窗口不消失,导致界面不能进行任何操作,这是线程没中断引起的吗?我是在一个主main函数中执行的流程 JProgressBar comp = new JProgressBar(); //进度条 int value = 0; private boolean bg001=true; JDialog dialog = new JDialog((F

Java并发编程示例(一):线程的创建和执行_java

开门见山 在IT圈里,每当我们谈论并发时,必定会说起在一台计算机上同时运行的一系列线程.如果这台电脑上有多个处理器或者是一个多核处理器,那么这时是实实在在的"同时运行":但是,如果计算机只有一个单核处理器,那么这时的"同时运行"只是表象而已. 所有的现代操作系统全部支持任务的并发执行.你可以边听音乐,边上网看新闻,还不耽误首发电子邮件.我们可以说,这种并发是 进程级并发 .在进程内部,我也可以看到有许许多多的并发任务.我们把运行在一个进程里面的并发任务称 线程. 和

怪问题,是不是程序执行太快,以致于数据库来不及更新就被显示出来了?

问题描述 ASP.NET中,更新Access数据库(增.删.改),然后把信息显示到datagrid里面:我先写了更新语句,然后才把数据绑定到datagrid中,奇怪的是datagrid中居然没反应,但数据库里确实是更新了,此时要手动刷新下页面才会显示更新结果...做了个实验:用单步调试,让时间拖的久些,居然一次就使datagrid更新了,不用再刷新页面:再次实验:在更新语句和绑定语句前加了一个空循环拖延时间,datagrid又是一次就更新了.请问各位,这个问题是不是因为程序执行太快,以致于数据库

《OpenACC并行程序设计:性能优化实践指南》一 3.5 在应用程序执行期间记录性能信息

3.5 在应用程序执行期间记录性能信息 应用程序将自动使用第一个插装事件启动Score-P性能监视器.使用几个环境变量来配置性能监视器.为了尽量减小运行时间扰动,Score-P默认设置产生一个基于性能分析的事件,这个事件不包含任何加速器活动.为了设置Score-P来记录PCIonGPU示例相关的活动,图3-5展示了与设置有关的环境变量.为了在Score-P 3.0版本中跟踪OpenACC API活动,将环境变量SCOREP_OPENACC_ENABLE设置为"yes".Score-P文

《Android App开发入门:使用Android Studio 2.X开发环境》—— 2-2 Android 程序的设计流程

2-2 Android 程序的设计流程 Android程序设计是把程序代码和资源(Resource)分开设计的."资源"包含界面的安排.字符串对象.图形对象.音乐对象等,这些对象都以文件的方式存放在项目的 res 文件夹下,再构建(Build)起来成为 .apk 文件,最后由用户下载安装到手机上使用. Android 的资源以视觉部分最多,其他也包含音乐.字符串等资源,为解说方便,除非在特别谈到音乐.字符串等资源时,否则我们多以视觉资源为代表. 视觉设计和程序逻辑 原本 Android