版权声明:博客地址:http://blog.csdn.net/muyang_ren。源代码能够在我的github上找看看 https://blog.csdn.net/muyang_ren/article/details/36238457

环境搭建

    硬件环境:J-link v8、mini2440、J-link转接板、串口转USB线

    软件环境:windows7(32位)、开发板uboot(NandFlash)、J-link驱动(J-Link ARM V4.10i)、SecureCRT、ADS1.2

    其中ADS里的AXD设置:载入JlinkRDI.dll+Options->Configure Interface...,在Session File一页中选择“Run Configuration
Script”,将该name.txt文本文件作为一个脚本加进来,确定。

name.txt内容

Setmem 0x53000000 0x00000000 32
Setmem 0x4A000008 0xFFFFFFFF 32
Setmem 0x4A00001C 0x000007FF 32
Setmem 0x53000000 0x00000000 32
Setmem 0x56000050 0x000055AA 32
Setmem 0x4C000014 0x00000007 32
Setmem 0x4C000000 0x00FFFFFF 32
Setmem 0x4C000004 0x00061012 32
Setmem 0x4C000008 0x00040042 32
Setmem 0x48000000 0x22111120 32
Setmem 0x48000004 0x00002F50 32
Setmem 0x48000008 0x00000700 32
Setmem 0x4800000C 0x00000700 32
Setmem 0x48000010 0x00000700 32
Setmem 0x48000014 0x00000700 32
Setmem 0x48000018 0x0007FFFC 32
Setmem 0x4800001C 0x00018005 32
Setmem 0x48000020 0x00018005 32
Setmem 0x48000024 0x008E0459 32
Setmem 0x48000028 0x00000032 32
Setmem 0x4800002C 0x00000030 32
Setmem 0x48000030 0x00000030 32

RTC实现功能

    RTC开节拍中断、闹钟中断。
    节拍中断——串口输出时间  XXXX年XX月XX日XX时XX分XX秒  和  LED闪亮
    闹钟中断——beep声  和 LED亮  5秒

RTC概述
    实时时钟(RTC)单元能够在当系统电源关闭后通过备用电池工作。

RTC能够通过使用STRB/LDRB ARM操
    作发送8位二-十进制交换码(BCD)值数据给CPU。

这些数据包含年、月、日、星期、时、分和秒的时间信息。

    RTC单元工作在外部32.768kHz晶振而且能够运行闹钟功能。
特性
–  BCD数:年、月、日、星期、时、分和秒
–  闰年发生器
–  闹钟功能:闹钟中断或从掉电模式唤醒
–  已解决的2000年问题
–  独立电源引脚(RTCVDD)
–  支持RTOS内核时钟节拍(tick)的毫秒节拍时间中断

    由图可知因为RTC秒有RTCRST复位寄存器,当RTC寄存器被赋值后,秒寄存器数值自己主动1s(1s=(1/1HZ),

1HZ为2^15时钟分频器产生的1HZ)加一,秒寄存器到60时被复位寄存器置零,分寄存器加一,以此类推。

RTC实时时钟

    实时时钟的值是存放在BCD寄存器里(BCD码)。BCD码是4位二进制码表示1位十进制数。
实时时钟初始化(赋值) RTCCON寄存器的使用
读写BCD 寄存器的时候仅仅须要将RTCCON寄存器RTCEN(读写)使能。其它为初始值

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXV5YW5nX3Jlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

实时时钟初始化代码

开BCD读写使能

rRTCCON |=0x01;  //RTCCON仅仅控制BCD寄存器,ALM数据寄存器就不须要读写使能了

BCD寄存器赋值。

   rBCDSEC    =0x0;   //14年6月12日1点1分0秒 星期4
rBCDMIN =0x01;
rBCDHOUR =0x01;
rBCDDAY =0x4; //星期
rBCDDATE =0x12;
rBCDMON =0x6;
rBCDYEAR =0x14;

BCD寄存器赋值完毕后必须将读写关闭,防止数据异常

rRTCCON &=~0x01;

之后BCD寄存器里的值開始计时

节拍中断使能

    始终节拍发生器能够产生节拍中断,据用户手冊:

RTC节拍时间是用于中断请求。TICNT寄存器有一个中断使能位和中断的计数值。当节拍时间中断发生时计

数值达到'0'。然后中断周期例如以下:

—  周期 = ( n+1 ) / 128 秒

—  n:节拍时间计数值(1至127)

此RTC时间节拍可能被用于实时操作系统(RTOS)内核时间节拍。

假设时间节拍是由RTC时间节拍所产生的,RTOS与时间的功能将通常同步到实际时间。

由此可知节拍中断产生的时间能够精确到(n+1 ) / 128 秒。n为1-127区间的取值。

TICNT   [7]    节拍时间中断使能。

TICNT   [6:0]   节拍时间计数值(1至127)。

节拍中断使能代码

rTICNT |= (1<<7) | 127; //节拍中断使能 计时寄节拍设置1s  1s=(127+1)/128

注意:这里仅仅是开了中断使能产生节拍中断INT_TICK,并没有开中断

闹钟中断使能

闹钟功能

RTC在掉电模式中或正常工作模式中的指定时间产生一个闹钟信号。在正常工作模式中,仅仅激活闹钟中断(INT_RTC)信号。在掉电模式中,除了INT_RTC 之外还激活电源管理唤醒(PMWKUP)信号。RTC闹钟寄存器(RTCALM)决定了闹钟使能/禁止状态和闹钟时间设置的条件。

   我们是在正常模式中产生INT_RTC(闹钟)中断信号源的。使能闹钟中断。当ALM寄存器(年、月、日、时、分、秒)的值与BCD寄存器(年、月、日、时、分、秒)值相等时产生中断信号。RTCALM寄存器是决定ALM闹钟使能和闹钟时间的,当RTCALM使能分秒的时候,仅仅确认ALM寄存器(分、秒)的值与BCD寄存器(分、秒)值是否相等即产生中断信号。

    ALM寄存器是须要赋值的。但并没有BCD寄存器那样的读写使能。而是直接赋值的。

闹钟中断使能

rRTCALM = 0x41;        //全局闹钟使能,秒闹钟使能(0b1000001)

ALM闹钟寄存器赋值

    rALMYEAR =0x14;  //年
rALMMON =0x06; //月
rALMDATE =0x12; //日
rALMHOUR =0x01; //时
rALMMIN =0x01; //分
rALMSEC =0x03; //秒

中断函数

概述

    S3C2440A中的中断控制器接受来自60个中断源的请求。提供这些中断源的是内部外设,如DMA控制器、UART、IIC等等。在这些中断源中,UARTn、AC97和EINTn中断对于中断控制器而言是“或”关系。当从内部外设和外部中断请求引脚收到多个中断请求时,中断控制器在仲裁步骤后请求ARM920T内核的FIQ或IRQ。仲裁步骤由硬件优先级逻辑决定而且写入结果到帮助用户通告是各种中断源中的哪个中断发生了的中断挂起寄存器中。

闹钟中断和节拍中断是没有sub寄存器的,通过图14-1能够看出中断发生是:

中断请求中断服务>>SRCPND>>仲裁>>
INTPND>>irq中断

中断挂起寄存器

S3C2440A有两个中断挂起寄存器:源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND)。

这些挂起寄存器表明一个中断请求是否为挂起。其中断源请求中断服务,SRCPND寄存器的对应位被置位为1。而且同一时候在仲裁步骤后INTPND 寄存器仅有1位自己主动置位为1。假设屏蔽了中断。则SRCPND寄存器的对应位被置位为1。这并不会引起INTPND 寄存器的位的改变。当INTPND 寄存器的挂起位为置位,每当I
标志或F标志被清除为0中断服务程序将開始。SRCPND和INTPND寄存器能够被读取和写入。因此服务程序必须首先通过写1到SRCPND寄存器的对应位来清除挂起状态而且通过同样方法来清除INTPND寄存器中挂起状态。

最后一句话能够知道开启中断须要SRCPND和INTPND寄存器清除挂起状态

中断屏蔽开启可服务代码

                                            // 注意点(二)
rINTMSK &= ~(0x1<<8);  // 中断屏蔽开启可服务(此中断使能不能放在中断入口函数内,因
                                            // 为中断使能并非中断的操作。而是进中断前的一个控制)

节拍中断函数入口代码

pISR_TICK=(unsigned)tick_interrupt; //告诉中断处理中断函数的入口地址  

void __irq alm_interrupt(){   //中断入口函数
rSRCPND|=0x1<<30; //清除中断挂起状态
rINTPND|=0x1<<30; //清除中断挂起状态
//中断功能代码块
Uart_Printf("\n\n ************************************* ");
Uart_Printf("\n 闹钟时刻。5秒 ");
Uart_Printf("\n ************************************* \n");
rGPBDAT=LED_ON; //点亮LED
Beep(2000, 4000); // 因为产生中断会有一秒的时间,所以实际是用了4+1秒这个中断 // 注意点(一)
rSRCPND &=(0x1<<30); // 当产生中断的时候,必须在开了中断功能后关闭中断清除
rINTPND &=(0x1<<30); // 而且关闭中断清除的控制必须在此中断入口函数由此中断控制
// (rSRCPND rINTPND置零,包含没用到的rSUBSRCPND)都应该在中断
// 入口函数里操作,而且入口函数最后也别忘了关闭中断清除
// (rSRCPND rINTPND,rSUBSRCPND置零)
// 假设没有关闭中断,将无限实现闹钟中断功能,其它中断不能进行
}

调试总结

(一)  RTC非中断串口打印时间不连续问题(BCD码)

       由来:之前写了一个非中断打印RTC实时时钟的代码,发现时间由9跳到16,后面发现是打印格式是十进制的原因,

 

       解决方法:数据在RTC里是BCD码存储。十进制的。可是取出来的时候,BCD码是四位二进制表示,最高位仅仅是9,

     10时BCD码(大端存储)是0001 0000。在这时假设採取进制转换成10进制就是16,可是假设继续使用16进制显示就没

     问题了。还是10

(二)  调试程序。中断没问题却发生串口代码while(!(rUTRSTAT0 & 0x2));出不来问题

     解决方法:

     main函数添加:

    U32 mpll_val = 0,consoleNum;
Port_Init(); //定义在2440lib.c
mpll_val = (92<<12)|(1<<4)|(1);
//init FCLK=400M,
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //定义在2440lib.c
ChangeClockDivider(14, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit 定义在2440lib.c
cal_cpu_bus_clk(); //HCLK=100M PCLK=50M consoleNum = 0; // Uart 1 select for debug.
Uart_Init( 0,115200 ); //定义在2440lib.c
Uart_Select( consoleNum ); //定义在2440lib.c

cal_cpu_bus_clk()定义例如以下:

static U32 UPLL;
static U32 cpu_freq;


//************************[ HCLK=100M   PCLK=50M ]***************************
void cal_cpu_bus_clk(void)
{
U32 val;
U8 m, p, s; val = rMPLLCON;
m = (val>>12)&0xff;
p = (val>>4)&0x3f;
s = val&3; //(m+8)*FIN*2 不要超出32位数!
FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; val = rCLKDIVN;
m = (val>>1)&3;
p = val&1;
val = rCAMDIVN;
s = val>>8; switch (m) {
case 0:
HCLK = FCLK;
break;
case 1:
HCLK = FCLK>>1;
break;
case 2:
if(s&2)
HCLK = FCLK>>3;
else
HCLK = FCLK>>2;
break;
case 3:
if(s&1)
HCLK = FCLK/6;
else
HCLK = FCLK/3;
break;
} if(p)
PCLK = HCLK>>1;
else
PCLK = HCLK; if(s&0x10)
cpu_freq = HCLK;
else
cpu_freq = FCLK; val = rUPLLCON;
m = (val>>12)&0xff;
p = (val>>4)&0x3f;
s = val&3;
UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
UCLK = (rCLKDIVN&8)? (UPLL>>1):UPLL;
}

RTC闹钟中断,节拍中断代码

Main函数代码

#define GLOBAL_CLK      1
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h" //函数声明
#include "2440slib.h"
#include "mmu.h"
#include "profile.h" //功能代码声明处
extern void RTC_Display_TICK_ALM(void); void Main(void)
{
U32 mpll_val = 0,consoleNum;
Port_Init(); mpll_val = (92<<12)|(1<<4)|(1); //init FCLK=400M,
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(14, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit
cal_cpu_bus_clk(); //HCLK=100M PCLK=50M consoleNum = 0; // Uart 1 select for debug.
Uart_Init( 0,115200 );
Uart_Select( consoleNum ); Beep(2000, 100); //>>>>>>>>>>>>>>下面是功能代码块入口<<<<<<<<<<<<<<<<<<<
RTC_Display_TICK_ALM(); //闹钟中断显示实时时钟,报警中断(调试成功!)
}

RTC_Display_TICK_ALM函数代码

#include "2440addr.h"     //引脚宏定义
#include "def.h" // U8 U32宏定义
#include "2440lib.h" //使用Uart_Printf,Dalay声明,Uart_Printf定义在2440lib.c文件
#include "option.h"
#include "mmu.h" #define LED_OFF (0x0f<<5)
#define LED_ON (~0x0f<<5) struct Time{ //RTC时间结构
U32 year;
U8 month;
U8 day;
U8 week;
U8 hour;
U8 mi;
U8 sec;
}ttime_rtc; void RTC_set()
{
rRTCCON |=0x01; rBCDSEC =0x0; //14年6月12日1点1分0秒 星期4
rBCDMIN =0x01;
rBCDHOUR =0x01;
rBCDDAY =0x4; //星期
rBCDDATE =0x12;
rBCDMON =0x6;
rBCDYEAR =0x14; rRTCCON &=~0x01;
} void Led_Init(){
rGPBCON=0x015400; //GPB5 GPB6 GPB7 GPB8 初始化为输出
rGPBDAT=LED_OFF; //熄灭状态
} //从RTC读取值
void read_for_rtc()
{
rRTCCON |=0x01; //RTCCON仅仅控制BCD寄存器,ALM数据寄存器就不须要读写控制了 ttime_rtc.year =0x2000+rBCDYEAR;
ttime_rtc.month =rBCDMON;
ttime_rtc.day =rBCDDATE;
ttime_rtc.week =rBCDDAY;
ttime_rtc.hour =rBCDHOUR;
ttime_rtc.mi =rBCDMIN;
ttime_rtc.sec =rBCDSEC; rRTCCON &=~0x01;
} void ALM_set(){ // 闹钟赋值 rALMYEAR =0x14;
rALMMON =0x06;
rALMDATE =0x12;
rALMHOUR =0x01;
rALMMIN =0x01;
rALMSEC =0x03; } void RTC_display(){
Uart_Printf("\n");
Uart_Printf("\n<><><><><><><><><><><><><><><><><><><><><><><><><><><><>\n");
Uart_Printf("**************HELLO RTC闹钟中断、节拍中断*****************\n\n");
Uart_Printf("#rTICNT: (1<<7) | 127 同意节拍使能\n",rTICNT);
Uart_Printf("#rRTCALM: 0b1000001 同意闹钟使能 秒精度闹钟\n",rRTCALM);
Uart_Printf("#rINTMSK: ~(0x1<<8) 开启INT_TICK中断源服务\n");
Uart_Printf("#rINTMSK: ~(0x1<<30) 开启INT_RTC 中断源服务\n");
Uart_Printf("#rSRCPND rINTPND 中断控制器清除对应位再关闭\n");
Uart_Printf("#\n#通过RTC节拍中断,串口输出开发板系统时间\n");
Uart_Printf("#XXXX年XX月XX日XX时XX分XX秒 | LED闪亮\n");
Uart_Printf("#而且可设置闹钟,闹钟到时,beep声|LED亮\n");
Uart_Printf("<><><><><><><><><><><><><><><><><><><><><><><><><><><><>\n\n\n\n");
} void __irq tick_interrupt(){
rSRCPND|=0x1<<8; //清除中断挂起状态
rINTPND|=0x1<<8; //中断功能代码块 rGPBDAT =~(rGPBDAT>>5)<<5 ; //LED灯 亮闪状态切换(这样运算不会影响到蜂鸣器)
read_for_rtc();
Uart_Printf("\n RTC time: %x年%2x月%02x日--%02x:%02x:%02x 星期%d",ttime_rtc.year,ttime_rtc.month,ttime_rtc.day,ttime_rtc.hour,ttime_rtc.mi,ttime_rtc.sec,ttime_rtc.week); //rTICNT &= ~(1<<7); //当仅仅使用一次中断的时候关闭模块使能
rSRCPND &=(0x1<<8);
rINTPND &=(0x1<<8); } void __irq alm_interrupt(){ //中断入口函数 rSRCPND|=0x1<<30;
rINTPND|=0x1<<30; //中断功能代码块 Uart_Printf("\n\n ************************************* ");
Uart_Printf("\n 闹钟时刻! 5秒 ");
Uart_Printf("\n ************************************* \n");
rGPBDAT=LED_ON; //点亮LED
Beep(2000, 4000); // 因为产生中断会有一秒的时间,所以实际是用了4+1秒这个中断 // 注意点(一)
rSRCPND &=(0x1<<30); // 当产生中断的时候,必须在开了中断功能后关闭中断清除
rINTPND &=(0x1<<30); // 而且关闭中断清除的控制必须在此中断入口函数由此中断控制
// (rSRCPND rINTPND置零,包含没用到的rSUBSRCPND)都应该在中断
// 入口函数里操作,而且入口函数最后也别忘了关闭中断清除
// (rSRCPND rINTPND,rSUBSRCPND置零)
// 假设没有关闭中断。将无限实现闹钟中断功能。其它中断不能进行
} void RTC_TICK(){ rTICNT |= (1<<7) | 127; //节拍中断使能 计时寄节拍设置1s // 注意点(二)
rINTMSK &= ~(0x1<<8); // 中断屏蔽开启可服务(此中断使能不能放在中断入口函数内,因
// 为中断使能并非中断的操作,而是进中断前的一个控制) pISR_TICK=(unsigned)tick_interrupt; //告诉中断处理中断函数的入口地址
} void RTC_ALM(){ rRTCALM = 0x41; //全局闹钟使能,秒闹钟使能(0b1000001) rINTMSK &= ~(0x1<<30);
pISR_RTC =(unsigned)alm_interrupt; } void RTC_Display_TICK_ALM() // 子main函数
{
//MMU_EnableICache();这一点至关重要, 不要关闭mmu,否则中断不能正常使用
MMU_Init();
Led_Init(); //led1 2 3 4输出。初始化熄灭状态
RTC_display(); //打印对应信息 RTC_set(); //rtc赋值
ALM_set(); // ALM闹钟赋值 RTC_TICK(); //节拍中断
RTC_ALM(); //闹钟中断 while(1)
{ }
}

输出截图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXV5YW5nX3Jlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

mini2440裸机试炼之—RTC闹钟中断,节拍中断的更多相关文章

  1. mini2440裸机试炼之——看门狗中断和复位操作

    看门狗的工作原理: 设本系统程序完整执行一周期的时间是Tp,看门狗的定时周期为Ti,Ti>Tp,在程序正常执行时,定时器就不会溢出,若因为干扰等原因使系统不能在Tp时刻改动定时器的记数值,定时器 ...

  2. mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信

    这个仅仅能作为自己初步了解MDA的开门篇 实现功能: 将字符串数据通过DMA0通道传递给UTXH0,然后在终端 显示.传输数据完后.DMA0产生中断,beep声, LED亮. DMA基本知识 计算机系 ...

  3. mini2440裸机试炼之——Uart与pc端实现文件、字符传输

    1.  波特率(Baud rate)即调制速率,1波特即指每秒传输1个符号. 2.  非FIFO模式,即数据传输不利用FIFO缓存,一个字节一个字节地传输. 3.  位能够用来推断发送缓存器中是否为空 ...

  4. mini2440裸机音乐播放器(非常久曾经的笔记)

    [这是好久曾经写的.有点乱,没时间整理.当做记录用的.] 图片粘贴失效.没上传图,想要的直接下载文档吧. 项目目的:通过IIS,触摸屏,LCD模块实现音乐播放器功能(button上一首.下一首.播放. ...

  5. mini2440裸机之I2C

    // File Name : IIC.c // Function  : S3C2440 IIC-bus Master Tx/Rx mode Test Program //             (I ...

  6. 软中断与硬中断 & 中断抢占 中断嵌套

    参考了这篇文章:http://blog.csdn.net/zhangskd/article/details/21992933 从本质上来讲,中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通 ...

  7. linux内核分析笔记----中断和中断处理程序【转】

    转自:http://www.cnblogs.com/hanyan225/archive/2011/07/17/2108609.html 中断还是中断,我讲了很多次的中断了,今天还是要讲中断,为啥呢?因 ...

  8. (转) 中断处理程序&中断服务例程

             关于中断处理程序和中断服务例程ISR的区别及联系,之前一直搞混,今天抽时间将两者关系弄弄清楚.ok,下面进入主题.       首先中断处理程序(Interrupt Handler) ...

  9. linux内核分析笔记----中断和中断处理程序

    中断还是中断,我讲了很多次的中断了,今天还是要讲中断,为啥呢?因为在操作系统中,中断是必须要讲的.. 那么什么叫中断呢, 中断还是打断,这样一说你就不明白了.唉,中断还真是有点像打断.我们知道linu ...

随机推荐

  1. [CF833B] The Bakery

    Description 将一个长度为n的序列分为k段 使得总价值最大一段区间的价值表示为区间内不同数字的个数 \(n\leq 35000,k\leq 50,1\leq a_i\leq n\) Solu ...

  2. 网络编程socket之一

    从今年10月22号开始我的python学习之路,一个月下来,磕磕碰碰,勉勉强强把基础部分算是学完了,一个月走过来,我过着别人看似单调,重复的生活,确实是,每天,每周都是一样的生活模式,早上7点40起床 ...

  3. [转]微擎MVC

    本文转自:https://www.kancloud.cn/donknap/we7/134626 控制器 控制器以文件夹.文件的形式组织,位于系统的 source 目录下,每一个目录代表一个 contr ...

  4. 声明父类new子类

    基本概念 这个实例是子类的,但是因为你声明时是用父类声明的,所以你用正常的办法访问不到子类自己的成员,只能访问到从父类继承来的成员. 在子类中用override重写父类中用virtual申明的虚方法时 ...

  5. Hadoop HDFS 设计随想

    目录 引言 HDFS 数据块的设计 数据块应该设置成多大? 抽象成数据块有哪些好处? 操作块信息的命令 HDFS 中节点的设计 有几种节点类型? 用户如何访问 HDFS? 如何对 namenode 容 ...

  6. Spring MVC异常处理 和 重定向传递数据

    1.异常处理介绍 Spring在web项目中,如果在请求处理时出现异常,那输出会是Servlet响应.这时异常需要以某种方式转换为响应. Spring将异常转换为响应的方式: a.特定的Spring异 ...

  7. VUE路由转场特效,WebAPP的前进与后退

    一.效果图 二.思路 1. 定义两个 CSS 过度动画,前进与后退: slide-right-enter   和   slide-left-enter 2. 给路由配置meta信息,设置各个路由的级别 ...

  8. 卷积神经网络CNNs的理解与体会

    https://blog.csdn.net/shijing_0214/article/details/53143393 孔子说过,温故而知新,时隔俩月再重看CNNs,当时不太了解的地方,又有了新的理解 ...

  9. “由于无法验证发行者,所以WINDOWS已经阻止此软件”的解决方法

    Vista 和 Windows7 系统都很注重系统的安全性,在提高安全性的同时,也给我们某些应用带来不便,例如需要安装插件或证书,可能会弹出“由于无法验证发行者,所以WINDOWS已经阻止此软件”的相 ...

  10. Java并发编程(二)同步

    在多线程的应用中,两个或者两个以上的线程需要共享对同一个数据的存取.如果两个线程存取相同的对象,并且每一个线程都调用了修改该对象的方法,这种情况通常成为竞争条件.  竞争条件最容易理解的例子就是:比如 ...