1. 可见性

如果一个线程对共享变量值的修改,能够及时的被其他线程看到,叫做共享变量的可见性。如果一个变量同时在多个线程的工作内存中存在副本,那么这个变量就叫共享变量

2. JMM(java内存模型)

多个线程同时对主内存的一个共享变量进行读取和修改时,首先会读取这个变量到自己的工作内存中成为一个副本,对这个副本进行改动之后,再更新回主内存中变量所在的地方。

(由于CPU时间片是以线程为最小单位,所以这里的工作内存实际上就是指的物理缓存,CPU运算时获取数据的地方;而主内存也就是指的是内存,也就是原始的共享变量存放的位置)

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAk4AAAFfCAIAAAA3WdQBAAAgAElEQVR4nO2c3XMc1ZmH9S/kD0hV7pPLXAxiMVA4xJZsKVzs5sIZwMTrZI13DSEFWQOylVSRYhaESIIXDFkvrJPlI8aVcmQIkrMW5XJU3nxUgOBgF4uJCY5iQlygxGWrXGcv2hrPdE/36Zk+57znnH6e+hUljbqnX/V51L/WaPCQAgAAiJoh6QEAAADsQtUBAEDkUHUAABA5VB0AAEQOVQcAAJFD1QEAQORQdQAAEDlUHQAARA5VBwAAkUPVAQBA5FB1AAAQOVQdAABEDlUHAACRQ9UBAEDkUHUAABA5VB0AAEQOVQcAAJFD1QEAQORQdQAAEDlUHQAARI7Tqtv13Hyj2SKe51u7D7q0wiw4FkpkNcOTIGJQEqdVJ37iSMm4tMIs4qeOlA+eEG1MrbhA1bk8IvRL6GsU+vw1QXyZxAcALVQdWCT0NQp9/pogvkziA4AWqg4sEvoahT5/TRBfJvEBQAtVBxYJfY1Cn78miC+T+ACghaoDi4S+RqHPXxPEl0l8ANBC1YFFQl+j0OevCeLLJD4AaKHqwCKhr1Ho89cE8WUSHwC0UHVgkdDXKPT5a4L4MokPAFqoOrBI6GsU+vw1QXyZxAcALVQdWCT0NQp9/pogvkziA4AWqg4sEvoahT5/TRBfJvEBQAtVBxYJfY1Cn78miC+T+ACghaoDi4S+RqHPXxPEl0l8ANBC1YFFQl+j0OevCeLLJD4AaKHqwCKhr1Ho89cE8WUSHwC0UHVgkdDXKPT5a4L4MokPAFqoOrBI6GsU+vw1QXyZxAcALVQdWCT0NQp9/pogvkziA4AWqg4sEvoahT5/TRBfJvEBQAtVBxYJfY1Cn78miC+T+ACghaoDi4S+RqHPXxPEl0l8ANBC1YFFQl+j0OevCeLLJD4AaKHqwCKhr1Ho89cE8WUSHwC0UHVgkdDXKPT5a4L4MokPAFqoOrBI6GsU+vw1QXyZxAcALVQdWCT0NQp9/pogvkziA4AWqg4sEvoahT5/TRBfJvEBQAtVZ4uhofTZSB7JPl68V9B4vkZaPJ8fxxLEl0l8gGLwRFF19sjTq+eX2o8ndH7cidWBbeD5GmnxfH4cSxBfJvEBisETRdVZoqcKWqs6NyiwMyB8XqMy+Dw/jrURXybxAQrAkwSqzgo9b5pSt0gFeyn08gOf58exNuLLJD5AAXiSQNWZp0CpYkX61uvg5qGhoeHpkxUHtoe3a1QSb+d34djJ6eErT7n5oJG57SC+TOID5OHkWnRwcwieUHWGGeom9aUyu2SN7PVsV65DVJ09/JzfiWMnp4fbZp2cHvbaM/FlEh+gJ3jSCVVni6xMWW+0u+Rxcnp4aGjzQXVws79qKeX9GmnxfH6rjnXht2jiyyQ+QDF4oqg6Swx1//pfoFRqsz6P47FZSim/16gMPs/vyjGllO+iiS+T+AAFuPRk5RbcR6g68+RZknIu+9VOw3q+aJDZy+8rkMdrVBJv53fomFJ+X8KUB8skPkAeTj3x+vVLqs40BUJ0qpPdK/Xf7F69oOrs4uf8bh3z/RKmPFgm8QF64sqTjrel+Hs7RNVZoODCkXfXTNX5ibfzO3TM+6LzYJnEB8jDoSdK+f2WcKrOKcU3Vqmv6l8xoOosE+L8Zh07uNnve3WllAfLJD7AAJi+FiX4+1I3VWeLvBcNtC8dlHlwBarOLp7Pb9uxIHpOebBM4gMU4+RalHByetjTKxJVZ5i8u54Cz3puU/zgClSdXfyc341jAbxwuYL4MokP0BMXnpycHu64GfLZGarOPCkh8mwr0KvnKwadu3T9QxYJXt58e7tGJfF2fvuOdf4TGF47pjxYJvEB8nB+LfK05xRVJ0iBXtEQ+hqFPn8dHFMeLJP4ABWpgydUHVgk9DUKff6aIL5M4gOAFqoOLBL6GoU+f00QXybxAUALVQcWCX2NQp+/Jogvk/gAoIWqA4uEvkahz18TxJdJfADQQtWBRUJfo9DnrwniyyQ+AGih6sAioa9R6PPXBPFlEh8AtFB1YJHQ1yj0+WuC+DKJDwBaqDqwSOhrFPr8NUF8mcQHAC1UHVgk9DUKff6aIL5M4gOAFqoOLBL6GoU+f00QXybxAUALVQcWCX2NQp+/Jogvk/gAoIWqA4uEvkahz18TxJdJfADQQtWBRUJfo9DnrwniyyQ+AGih6sAioa9R6PPXBPFlEh8AtFB1YJHQ1yj0+WuC+DKJDwBaqDqwSOhrFPr8NUF8mcQHAC1UHVgk9DUKff6aIL5M4gOAFqoOLBL6GoU+f00QXybxAUALVQcWCX2NQp+/Jogvk/gAoIWqA4uEvkahz18TxJdJfADQQtWBRUJfo9DnrwniyyQ+AGih6sAioa9R6PNb4sOPL0iP0IX4MokP4AO+WZGCqgOLhL5Goc9via27Ft4+85H0FFcQXybxAXzANytSUHVgkdDXKPT5bTBz7PTIxOzXdh+THuQK4sskPoA4HlqRgqoDi4S+RqHPb5yl88sbWvNf+OahDa35w6+dkR7nMuLLJD6ALH5akYKqA4uEvkahz2+c3S+9tfultzZOHTn82pkNrfkLy5ekJ1LKg2USH0AWP61IQdVFhW9/GQ59jYKYf//Rd5fOLzs40OmzSxunjnz48YWNU0f++Je/PfjC63tmTzo4rhbxZRIfIAtWpKDqosK3vwyHvkZBzJ9cYhwc6Fv//Zv9R99tH/HDjy/8/QP/4+bQxYgvk/gAWbAiBVUXDx7+ZTj0NQpifjcXtaXzyw++8HrqiDPHTvvwtxnxZRIfIAtWpKDqIsHPvwyHvkZBzO/s/l3wiMWIL5P4AFmwIkXwVUeS3HDHD2+444drts+s+uruNfcebNz8kPhI7bi0wizip65M1myfGd44HfcRywRPZNfITytSMbXiTqtu0+Re8RPnSa6+7dE122eGb30ksW31XS9cv82Xk3PTnU+4tMIsQTjGRa0hrZmHnmBFNgYlcVp1/uPsTVCh/GUYbMBLVZAFK6xC1XXBX4bBAVzUIAtWWIWq6wLbwAFoBlmwwipUXRfYBg5AM8iCFVah6rrANnAAmkEWrLAKVdcFtoED0AyyYIVVqLousA0cgGaQBSusQtV1gW3gADSDLFhhFaquC2wDB6AZZMEKq1B1XWAbOADNIAtWWIWq6wLbwAFoBlmwwipUXRfYBg5AM8iCFVah6rrANnAAmkEWrLAKVdcFtoED0AyyYIVVqLousA0cgGaQBSusQtV1gW3gADSDLFhhFaquC2wDB6AZZMEKq1B1XWAbOADNIAtWWIWq6wLbwAFoBlmwwipUXRfYBg5AM8iCFVah6rrANnAAmkEWrLAKVdcFtoED0AyyYIVVqLousA0cgGaQBSusQtV1gW3gADSDLFhhFaquC2wDB6AZZMEKq1B1XWAbOADNIAtWWIWq6wLbwAFoBlmwwipUXRfYBg5AM8iCFVah6rrANnAAmkEWrLAKVdcFtoED0AyyYIVVqLousA0cgGaQBSusQtV1gW3gADSDLFhhFaquC2wDB6AZZMEKq1B1XWAbOADNIAtWWIWq6wLbwAFoBlmwwipUXRfYBg5AM8iCFVah6rrANnAAmkEWrLAKVdcFtoED0AyyYIVVqLousA0cgGaQBSusQtV1gW3gADSDLFhhFaquC2wDB6AZZMEKq1B1XWAbWGLp/PLMsdPJx+1F/8WJD94+85GDo6OZn2CFM6i6Lqg6sMSF5UsbWvPHT59TK4u+dH5549SR02eXHBwdzfwEK5xB1XVB1YE9Dr92ZuuuBbWy6LtfemvP7Ek3h95/9N2l88tujgV9gRVuoOq6oOrAKlt3Lcz+6g8bp44cfXNxQ2v+wvIl6YlAHqxwAFXXBVUHVnn7zEcbWvMbWvObv3P08GtnpMcBL8AKB1B1XVB1YJup/b8dmZj92u5j0oOAR2CFbag63gQFTvnw4wtf+OYhN3ZBKGCFbag64TdB1eovw5DAFQ2yYIVVqDqlRN8EBQAAtqHqLsOboAAAYoWquwxvggIAiBWZqnv/7LkXD/16eu/PtjzwrD/5h8mfjEzM3rTjJfFJZHP/YweePrBw4tSiiBtV8NMrssUnqZDE21iVxHXVnTi1uOWBZxvNlocZvvWRkft/evWXvys+iSe56c4n5n9xwrEhg+GzV6QzglIhSSixIYm7qvvg3NL9jx24/M3c/NB1X919413Pr/3Gj0f+9cfjk4c8ydjknPgMgll338zab/x4zd37rr/9+8O3PpIs1qbJvT7cjOcRhFd1jg9SIYnncSCJo6o7cWrxpjufaDRbw7c8vPqOH4zvnBU/uUSbNXfvu3rjo41ma9VtU6/8/E03qvQFXgUX91IhSXCxIYmLqjtxanHVbVONZuuaTd9bP/Gy+HkkfeW6LU8lN1k/efV1B7aUB6/CjTOpkCTcmJXEetV9cG4puaVa9ZXHuZ8KNDds+6/kDuuXb/7etjAlwavQ40AqJAk9BiWxXnX3TO9PbqlQLehcv3VPo9ka3frYhYte/NsueBVBbEuFJBHElCR2q+7EqcVGszV86yO8dBB8ds5es+l7jWbryRePWHUGr2oUm1IhSSQxJIndqrv5vv9sNFufu/OH8ueLVM6au/clLyaI/2KHV9HEnlRIEk2MSGKx6k69/+fkXU+8ehBNktsr2Xdj4lVksSEVkkSW6pJYrLqnDyw0mq3rb/+++GkiprL6jh80mq37HztgTxu8qltsSIUkkaW6JBarLvl/Nj//9RfETxMxlXX3zTSarS/e/ZQ9bfCqbrEhFZJEluqSWKy6TZN7G83W6PYD4qeJGEyj2frcVx61pw1e1TDGpUKS+FJREotVl/wfLbz9KbIk/2yPPW3wqoYxLhWSxJeKklivOvETRMwm+Qd77GmDVzWMcamQJL5UlISqI/2FqiPGQ9URbag64jRUHTEeqo5oQ9URp6HqiPFQdUQbqo44DVVHjIeqI9pQdcRpqDpiPFQd0YaqI05D1RHjoeqINlQdcRqqjhgPVUe0oeqI01B1xHioOqINVUechqojxkPVEW2oOuI0VB0xHqqOaEPVEaeh6ojxUHVEG6qOOA1VR4yHqiPaUHXEaag6YjxUHdGGqiNOQ9UR46HqiDZUHXEaqo4YD1VHtKHqrGRoaCj1wQD7Gt/Yh1B1Awep8kLV9Vw+POkMVWcl2JYXqm7gIFVeqLqey4cnnaHqihayDMUSGLet5FQFswUtXOheIVUQUnHxic8Tqs6YBz0303pgxOmAUvOqG3gRkaog8VXdwOuCJ3mh6izalnxQvFf2q2Ue6WueJGNfGh0aGvrE2mdkzyFVN9gi+ibV2LYtn7hyMRxtiJ5Dqi67mS+eTH77U354QtX1kTKr23kfZNW2zqMU34iNTT7zmU9efpyq882rEKUam3zmM5/89Ge2ddj1yS2rI5LKN0m0K965ap3b40k7VJ0t21LOlX/Ofm3TPr567aeHhkYbk9/+FFXnn1eBStWZsS+NDg1dvqKJhKprb4MneaHq+ojWtp53UgW/b/XcOO/B7HP2NeEYVeelV0FLlYSqc5AIPFm55w5SEqqux1e1rhR8teeTlDFSeyCqzk+vgpYqiewlbJyqC8GT5I+7gtcfqs6YbVqBtBv3ZV7buQI6n42q89OroKUa9+ASNk7VeexJ19tSPvttwRNI1fliW8/N8u6hej5YfCCqzk+vApdK/j0p41Rd/maeeJKk8dkh/lbXg5hsK7gvLvCp+KtUXRxeBS1V47ND4v+nwThV570nSS7fGAn9bkfVubCt4nNSdRF7Fa5UnvTcOFWXv5kPnrSTVJ3UJYiqy13g8hSvuie2UXXiXsUk1eq1n5Z912VnIqu6aDwZ27blEx03Q7LOUHXmY9C2oXKvIRRsNn7ZsG7k/j5c56qrEq+k6v4nMCKUKlBJsuvl2cUn4P8jharTC1Txxipvg76O4k+ousGCVAWh6gZbwVp5QtURp6HqiPFQdUQbqo44DVVHjIeqI9pQdcRpqDpiPFQd0YaqI05D1RHjoeqINlQdcRqqjhgPVUe0oeqI01B1xHioOqINVUechqojxkPVEW2oOuI0VB0xHqqOaFOLqkueMO/T8jsOdjivop3N9vDRVF3qRKU+NX6GB9vLTbSz2R4+oKpDm/KzmR2eqrPiSvm9ik9Cv0fUPo/2aQf7fp0JVx3xqkMq/6XysOrQRlaS2Kqu/HgD7NLzuHnDFAxp8FQ4O64p4arjvurKz4ZUnkjlQ9WVnxZtHEgSW9WZPZZS6uLypTLb5zHAoYufRPu0Vk9OdeGq48NvdUjluVQ+VJ3ZY6naaxNz1ZU8kKklV0r96dz5zm2UUheXL2n3KphhgO+35yPZD/o6Rf1OYk+46lT0quRRkGqws+SJVMarbuAT0u/2aGNJEq+rLu+8pz41suTtL3Vuo1bupLI79ns2LOnV8xnKH9G9cNWR+q0ub4OCHdtf6txGIZV9qfz5rS5vg4Ide66Lqr02VJ3mLGcpfv7Ux+0XDbQHNfVt9hw4+0GZ3W0MWfOqywOpvJLKt6rLA22cSRJn1blM8Uno3HLbq0tKKXX2nW2Th8YnD00dV0qphX39nYGC77346KZS26pDKnunKOKqc5nic9K5ZYjaUHX9Lflglmh3LP44ydjkGwtKKaUW9h0ae/yd99QV1YoH+Ov55faz5Q2T3UB7lkSEq46Hv9UhlW9S+VN1BUOijUtJ4qw67TOU30y7Y/FJSG08tm9RKaXU0ntnleq+jercPvWxVq+Cffs9UbaFq44/v9WV3CW7mXbH4jOAVFr8qTq0MaWN71U3tuOVKkqVpMzzDCBimR3ztu+579jkwo/Orgx0/I2Sz1OsV+qR4k+rZ/iWh32ousG86utASBWuVBUvPmiT9zyC2lSUxGLVbZrc22i21t03Y+rnwayRqtwLCBUPmtHr8usGSnW9YlD8PAV6pR7vOUDJb6RkGs3Wqtumir9rqzj2qt/xkMoHqdxffNAm9XjPAUp+IzYksVh190zvbzRba+/Zb8qbvE/72ld2r8t/DT6+2H6hvOe+qY//en5Zu1nxDIN9O9msn3i50WzddOcTpmXpA1Nepc5J6lOkCloqgxcftPFBm+qSWKy66b0/azRbN/zLM2bd6vd8ld+yc/vfnT7X/kbKbJ9H55Yrt1GLU23P1OIXJ+bGJucG08vI99tXPv/1FxrN1pYHnh3YiuoY8arnWer5YIhSTfWaM/Vx3FKZuvjUShufr0XVJbFYdb988/eNZuvq275j3K3yJ7ptSfljpTbu+eBgS5u8o/e9VxfGV14onzl2emRidnRibrxQ00Svkt9O+WkHyHVbnmo0W08fWMid1T7VvSo4RQVfCkWq9qd1lsrIxadW2nh+LaouicWqu3BxeXTrY41ma3T7AeNumdogta59bVP+VOQ97cjEbJL1O+bytlQdd1Llvx0jeqWyfuLlq25+qNFsvX/2XM9v0w0VvdKen+obyEpVZlQVu1TVLz5108bna5ERSSxWnVLq2Zf/t9FsXbPpe0Zsiyzrd86t3zk3OjG3fsfcyMSs+Dza3PDPTzearXum91t1Bq9qFXtSIUn5eH4tMiKJ3aq7cHH5i3c/ZeNFc3tZt2POyYHmktcKRifmxibn1u2cW7fTzXEHzNp79jearUazdeLUolVnYvWKZGNVqggk4Vo0bk4Su1WnlPr5b/4vGfTGu54XP2tlMrryt1mrWbdjLvG4fbiRiVkHxx3wnGw/kPxPLbuem7ctTEmC88ruAjmR1vDM9qUKXRKuRQYlsV51SqmnDywkwq2+4wfi505/ct3otXLf1D7c+h1z6x3dxPWXtffsT2zz4aXLTsLyyl6SF52SG/NQ4kyqoCWp+bXIrCQuqk4pteu5+US4VV953NQfii3F8Q2yz/fj6ydeTl4lT2y7cHHZjS3lCcgre+l8Q4H4MNq4lypcSWp7LbIhiaOqU0q98vM3V9021XbuxrueN/XP9gS93v7o1Zk1d++7/vbvJ+96ajRb03t/5syTfgnFK0vx/A0FnRGUKlBJangtsieJu6pTSn1wbunBPa8k30M7w7c8vGrzv/uTtfe+dO0/PRnr4bRJrc6WB5714X0oxQThlY1ct+Wptfe+dO1Xn0wsuvHu/avvel58Kj+lClGSWl2LbEvitOoS3j977sVDv77j315o32d5lTXbZ4Y3Tsd6uJLZNLn3yRePnHr/z+71GBivvLr29j1X3fKw7aN87us/uvb2PW2Lhm99ZO19L3uokz9SeSWJNjW8FtmTRKDqPGfj1JE//uVvsR4O3OBgWZfOLz/4wuupw80cO334tTNWjwvO4FpkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6tKgF1QHi6A6WGQQqi4NekF1sAiqg0UGoerSoBdUB4ugOlhkEKouDXpBdbAIqoNFBqHq0qAXVAeLoDpYZBCqLg16QXWwCKqDRQah6pRSaun88syx08nH7fX+xYkP3j7zke1Dx61XbeEiBYPBtcgSVJ1SSl1YvrShNX/89Dm1st5L55c3Th05fXbJ9qHj1qu2UHUwGFyLLEHVXebwa2e27lpQK+u9+6W39syedHDc/UffXTq/7OBA4BKqDgaGa5ENqLorbN21MPurP2ycOnL0zcUNrfkLy5ekJ4JQoeqgClyLjEPVXeHtMx9taM1vaM1v/s7Rw6+dkR4HAoaqgypwLTIOVdfF1P7fjkzMfm33MelBIGyoOqgI1yKzOK26Xc/NN5otnzN86yMj9//06i9/V3wSElyuuuXha7f8R/Lxmu0zwxunG83WNZsfd6BT+3AkmkRwLfrW7oMu+6UYp1UnfurLJGi3iGRufmjNvQf/7h8fa6x0z1W3PLxm+8zVtz1q+9DX3r7nqlselj8DxGgiuBa57JdiBKpufPIQIVFm/Y650Ym58clDoxNzY5Nz63fOrds5Jz4VIe5D1VF1JOaMTswlhbd+59zIxKz4PISIhKqj6kjMGZucG5mYHZmYHZmYW7+DX+lITUPVUXUk8qzbOTcyMZu8kklIPUPVUXUk/oxMzI5NUnWkvqHqqDoSf+g5UvNQdVQdIYREHqqOqiOEkMhD1VF1hBASeag6qo74kqGhIdt7DXYIQkIPVUfVEY8yQBVRdYRoQ9VRdSTsFLfXUD+Ify+EWApVR9URsQzQQFVKizIjtQ1VR9URj6Jto+wGZR4p+eSExBqqjqojHsVe1bUf5KVLUsNQdVQd8SgOqq7fIxISQag6qo54lH6rLvm054OpR/rqP0IiC1VH1RHJ9PsGk7xW63y8TB32fISQWEPVUXXEo/T1W11ftdcuvH7ft0lIBKHqqDriUcpXXcELkiVfq6TbSH1C1VF1xKOUrLri95hQdYSkQtVRdcSjDPAOzJLbUHWkzqHqqDriUag6QmyEqqPqiEy0773s+YaR4n4q+QJm8aughMQXqo6qIyFl4F/78t6uSUgdQtVRdYQQEnmoOqqOEEIiD1VH1RFCSOSh6qg6QgiJPFQdVUcIIZGHqqPqCCEk8lB1VB0hhEQeqo6qI4SQyEPVUXWEEBJ5qDqqjhBCIg9VR9URQkjkoeqoOkJ8SfKDmfdp+R0HOxyJOFQdVUeIL0l+MPM+7Wtf43sVX0zETx0pDlVH1RHiS5IfzLxPs1uWYYBdeh43b5iCIYk/oeqoOkJ8SfKDmfepvWMppS4uXyqzfR7ip44Uh6qj6ggRTskf2H53LDjcn86d79xGKXVx+ZJ2r4IZxM8hKQ5VR9UR4kuSH8y8T7Xbl9mx/aXObdTKb3XZHfu9qoifQ9IzVB1VR4gvSX4w8z7N2z6P4udPfdx+AVN7UBJiqDqqjhBfkvxg5n3qw2x5dG657dUlpZQ6+862yUPjk4emjiul1MI++W+hzqHqqDpCfEnyg5n3ad72PRlglzI7Fn+cZGzyjQWllFIL+w6NPf7Oe+pK7RGpUHVUHSG+JPnBzPt0gGcov5l2x+KLSWrjsX2LSimllt47qxS/0nkQqo6qI0Qyff3Mlnmevo6b/bjf7XvuOza58KOzKwMdf0P8JBOqjqojJLD0+5Ne5nkqHjS1cfs1TKV49dKLUHVUHSG+JPnBzPu0r31l97r8zpTji+0/2omf25qHqqPqCPEiyU9lmQfL767d/nenz7UvCGW2z6Nzy5Vf6Ran2p2nFqekT2/NQ9VRdYTIJ/mR7PdL7Q3ajVX+WKrX21L6eoa8ryb/d8F7ry6Md/zRLvmUSIWqo+oIEU7y82h1g/Fyf5nruU35S4r4mSR5oeqoOkIIiTxUHVVHCCGRh6qj6gghJPJQdVQdIYREHqqOqiOEkMhD1VF1hBASeag6QgghtYjLfinGadVtmtwrfuoJIYQ4yE13PuGyX4pxWnUAAADuoeoAACByqDoAAIgcqg4AACKHqgMAgMih6gAAIHKoOgAAiByqDgAAIoeqAwCAyKHqAAAgcpZoJyoAAAAjSURBVKg6AACIHKoOAAAih6oDAIDIoeoAACByqDoAAIic/wfDwiYpLa97ygAAAABJRU5ErkJggg==" alt="" />

两条规定:

a.线程对共享变量的所有操作必须在工作内存中进行,不能直接操作主内存

b.不同线程间不能访问彼此的工作内存中的变量,线程间变量值的传递都必须经过主内存

如果一个线程1对共享变量x的修改对线程2可见的话,需要经过下列步骤:

a.线程1将更改x后的值更新到主内存

b.主内存将更新后的x的值更新到线程2的工作内存中x的副本

所以,要实现共享变量的可见性必须保证下列两点:

a.线程对工作内存中副本的更改能够及时的更新到主内存上

b.其他线程能够及时的将主内存上共享变量的更新刷新到自己工作内存的该变量的副本上

Java中可以通过synchronized、volatile、java concurrent类来实现共享变量的可见性

3. synchronized实现可见性

synchronized 实际上是对访问修改共享变量的代码块进行加互斥锁,多个线程对synchronized代码块的访问时,某一时刻仅仅有一个线程在访问和修改代码块中的内 容(加锁),其他所有的线程等待该线程离开代码块时(释放锁)才有机会进入synchronized代码块。

所以某一个线程进入synchronized代码块前后,执行过程入如下:

a.线程获得互斥锁

b.清空工作内存

c.从主内存拷贝共享变量最新的值到工作内存成为副本

d.执行代码

e.将修改后的副本的值刷新回主内存中

f.线程释放锁

随后,其他代码在进入synchronized代码块的时候,所读取到的工作内存上共享变量的值都是上一个线程修改后的最新值。

多个线程之间执行共同的代码块(访问修改共享变量),由于线程交叉执行,最终共享变量的最后值可能有多种结果:

public class SynchronizedTest {

    private boolean ready = false;
private int result = 0;
private int number = 1; public void write(){
ready = true;
number = 2;
} public void read(){if(ready){
result = number * 3;
} System.out.println("result is " + result);
} private class TestThread extends Thread{
private boolean flag;
public TestThread(boolean flag){
this.flag = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(flag){
write();
}else{
read();
}
}
} public static void main(String[] args){
SynchronizedTest test = new SynchronizedTest();
test.new TestThread(true).start();
test.new TestThread(false).start();
}
}

如上代码,由于两个线程交叉执行,最后result的结果可能是0或者6或者3

共享变量不可见主要有下列原因:

a.线程的交叉执行

b.重排序

c.共享变量未能及时更新

通过使用synchronized可以保证原子性(synchronized代码块内容要么不执行,要执行就保证全部执行完毕)和可见性,修改后的代码为在write和read方法上加synchronized关键字

4. volatile实现可见性(jdk 1.5后)

volatile如何实现可见性?

volatile变量每次被线程访问时,都强迫线程从主内存中重读该变量的最新值,而当该变量发生修改变化时,也会强迫线程将最新的值刷新回主内存中。这样一来,不同的线程都能及时的看到该变量的最新值。

但是volatile不能保证变量更改的原子性:

比 如number++,这个操作实际上是三个操作的集合(读取number,number加1,将新的值写回number),volatile只能保证每一 步的操作对所有线程是可见的,但是假如两个线程都需要执行number++,那么这一共6个操作集合,之间是可能会交叉执行的,那么最后导致number 的结果可能会不是所期望的。

所以对于number++这种非原子性操作,推荐用synchronized:

synchronized(this){
number++;
}

如下代码:最后的number的结果不一定是500,有可能是比500小,因为number++不是一个原子性的操作,用volatile不能保证可见性

public class VolatileTest {

    public static int number = 0;

    public void increase(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
number++;
} /**
* @param args
*/
public static void main(String[] args) {
final VolatileTest test = new VolatileTest();
for(int i = 0 ; i < 500 ; i++){
new Thread(new Runnable() { @Override
public void run() {
test.increase(); }
}).start();
} //若当期依然有子线程没有执行完毕
while(Thread.activeCount() > 1){
Thread.yield();//使得当前线程(主线程)让出CPU时间片
} System.out.println("number is " + number);
} }

对于自增之类的非原子性操作,只能通过如下方式保证可见性:

a. synchronized

b. ReentrantLock

c. AtomicInteger

synchronized修改如下:

public void increase(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(this){
number++;
} }

ReentrantLock修改方式如下:

public class VolatileTest {

    public static int number = 0;
public Lock lock = new ReentrantLock(); public void increase(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} lock.lock(); try{
number++;//这块的代码实际项目中可能会出现异常,所以要捕获
}finally{
lock.unlock();//用try finally块保证Unlock一定要执行
} } 。。。
}

AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

修改如下:

package com.mooc.test;

import java.util.concurrent.atomic.AtomicInteger;

public class VolatileTest {

    public static AtomicInteger number = new AtomicInteger(0);

    public void increase(){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} number.getAndIncrement();//获得当前值并且加1
} /**
* @param args
*/
public static void main(String[] args) {
final VolatileTest test = new VolatileTest();
for(int i = 0 ; i < 500 ; i++){
new Thread(new Runnable() { @Override
public void run() {
test.increase(); }
}).start();
} //若当期依然有子线程没有执行完毕
while(Thread.activeCount() > 1){
Thread.yield();//使得当前线程(主线程)让出CPU时间片
} System.out.println("number is " + number.get());
} }

5. volatile适用情况

a.对变量的写入操作不依赖当前值

比如自增自减、number = number + 5等(不满足)

b.当前volatile变量不依赖于别的volatile变量

比如 volatile_var > volatile_var2这个不等式(不满足)

6. synchronized和volatile比较

a. volatile不需要同步操作,所以效率更高,不会阻塞线程,但是适用情况比较窄

b. volatile读变量相当于加锁(即进入synchronized代码块),而写变量相当于解锁(退出synchronized代码块)

c. synchronized既能保证共享变量可见性,也可以保证锁内操作的原子性;volatile只能保证可见性

Java多线程共享变量控制的更多相关文章

  1. Java多线程之控制执行顺序

    概念: 多线程在并发环境中的正常执行顺序是随机无序的,并不能按照期盼的结果输出. 因为启动一个线程时,线程并不会立即执行,而是等待CPU的资源调度,CPU能调度哪个线程,是通过多种复杂的算法计算而来. ...

  2. java多线程 -- Condition 控制线程通信

    Api文档如此定义: Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对 ...

  3. Java多线程 2 线程的生命周期和状态控制

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...

  4. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  5. Java多线程——线程的生命周期和状态控制

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...

  6. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  7. JAVA多线程 问题 转载

    参考:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ http://www.cn ...

  8. Java 多线程 锁 存款 取款

    http://jameswxx.iteye.com/blog/806968 最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣.已经拟好了提纲,大概分为这几个主题: ja ...

  9. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

随机推荐

  1. JAVA视频链接

    Java基础Java马士兵:链接:https://pan.baidu.com/s/1jJRvxGi密码:v3xb Java刘意:链接:https://pan.baidu.com/s/1kVZQCqr密 ...

  2. 剑指offer-第五章优化时间和空间效率(在字符串中第一次出现切只出现一次的字符)

    题目:在字符串中第一次出现切只出现一次的字符 思路:用HashMap来存放对应的char值和该char出现的次数.做一次变量就可以得到第一个只出现一次的字符. Java代码: import java. ...

  3. HTML`CSS_网站页面不同浏览器兼容性问题解决

    目前,最为流行的浏览器共有五个:分别是ie,Edge浏览器(属于微软),火狐,谷歌(chrome)Safari和Opera五大浏览器. Trident内核:IE ,360,,猎豹,百度: Gecko内 ...

  4. 委托的N种写法

    一.委托调用方式 1. 最原始版本: delegate string PlusStringHandle(string x, string y); class Program { static void ...

  5. 使用resteasy作为dubbox消费者

    dubbox服务提供者是REST风格的,消费者可能是从dubbox过来的,也可能是从第三方外部系统过来的.后者的话我们没得选,只能以服务提供者直连,服务治理平台和监控中心手再长,也管不到别人的地盘.但 ...

  6. simple_one_for_one 和 one_for_one的区别

    参考这里http://blog.sina.com.cn/s/blog_77cb45a70102v1ja.html 用起来最直观的不同点 simple_one_for_one需要手工start_chil ...

  7. 利用全局变量$_SESSION和register_shutdown_function自定义会话处理

    register_shutdown_function 可以注册一个自定义的函数,在程序运行结束之前 执行. 在做ecshop的二次开发过程中,虽然代码 太老太乱太冗余,但ec的会话处理的设计感觉还是不 ...

  8. CCPC2018-湖南全国邀请赛 G String Transformation

    G.String Transformation 题目描述 Bobo has a string S = s1 s2...sn consists of letter a , b and c . He ca ...

  9. Rest之路 - 搭建开发环境

    准备Jersey框架和类库 从官网 (https://jersey.java.net/download.html) 下载最新的zip文件,解压后如下图: lib: 包含Jersey的所有类库. ext ...

  10. linnx常用命令学习

    ll命令就相当于ls -l. [-][rwx][r-x][r--] [-] 代表这个文件名为目录或文件(d为目录-为文件) [rwx]为:拥有人的权限(rwx为可读.可写.可执行) [r-x]为:同群 ...