java同步锁如何使用_java 同步锁(synchronized)的正确使用姿势
關于線程安全,線程鎖我們經常會用到,但你的使用姿勢正確不,反正我用錯了好長一段時間而不自知。所以有了這篇博客總結下線程鎖的正確打開姿勢 廢話不說看例子 一,對整個方法進行加鎖 1,對整個方法進行加鎖,不同線程訪問同一個類的同一個對象
public class TestRunnable implements Runnable {
@Override
public synchronized void run() {
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
public static void main(String[] args)
{
TestRunnable runnable=new TestRunnable();
Thread threadA=new Thread(runnable,"threadA");
threadA.start();
Thread threadB=new Thread(runnable,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
2,對整個方法進行加鎖,不同線程訪問同一個類的不同對象
public class TestRunnable implements Runnable {
@Override
public synchronized void run() {
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
public static void main(String[] args)
{
TestRunnable runnableA=new TestRunnable();
Thread threadA=new Thread(runnableA,"threadA");
threadA.start();
TestRunnable runnableB=new TestRunnable();
Thread threadB=new Thread(runnableB,"threadB");
threadB.start();
}
運行結果: threadB—0
threadA—0
threadA—1
threadB—1
threadA—2
threadB—2
threadA—3
threadB—3
threadB—4
threadA—4
threadA—5
threadB—5
threadA—6
threadB—6
threadA—7
threadB—7
threadA—8
threadB—8
threadA—9
threadB—9
小結:對方法整體加鎖的做法適用條件是 多個線程訪問的必須是同一個類的同一個實例對象
一,對代碼塊進行加鎖 1,對代碼塊進行加鎖,加鎖對象為當前類對象,不同線程訪問同一個類的同一個對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (TestRunnable.this) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnable=new TestRunnable();
Thread threadA=new Thread(runnable,"threadA");
threadA.start();
Thread threadB=new Thread(runnable,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
2,對代碼塊進行加鎖,加鎖對象為當前類對象,不同線程訪問同一個類的不同對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (TestRunnable.this) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnableA=new TestRunnable();
Thread threadA=new Thread(runnableA,"threadA");
threadA.start();
TestRunnable runnableB=new TestRunnable();
Thread threadB=new Thread(runnableB,"threadB");
threadB.start();
}
運行結果: threadB—0
threadA—0
threadB—1
threadA—1
threadB—2
threadA—2
threadA—3
threadB—3
threadA—4
threadB—4
threadB—5
threadA—5
threadA—6
threadB—6
threadB—7
threadA—7
threadA—8
threadB—8
threadA—9
threadB—9
3,對代碼塊進行加鎖,加鎖對象為當前類(不是類對象哦),不同線程訪問同一個類的同一個對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (TestRunnable.class) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnable=new TestRunnable();
Thread threadA=new Thread(runnable,"threadA");
threadA.start();
Thread threadB=new Thread(runnable,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
4,對代碼塊進行加鎖,加鎖對象為當前類(不是類對象哦),不同線程訪問同一個類的不同對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (TestRunnable.class) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnableA=new TestRunnable();
Thread threadA=new Thread(runnableA,"threadA");
threadA.start();
TestRunnable runnableB=new TestRunnable();
Thread threadB=new Thread(runnableB,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
5,對代碼塊進行加鎖,加鎖對象為已賦值的變量,不同線程訪問同一個類的同一個對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("test") {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnable=new TestRunnable();
Thread threadA=new Thread(runnable,"threadA");
threadA.start();
Thread threadB=new Thread(runnable,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
6,對代碼塊進行加鎖,加鎖對象為已賦值的變量,不同線程訪問同一個類的不同對象
public class TestRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized ("test") {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
}
public static void main(String[] args)
{
TestRunnable runnableA=new TestRunnable();
Thread threadA=new Thread(runnableA,"threadA");
threadA.start();
TestRunnable runnableB=new TestRunnable();
Thread threadB=new Thread(runnableB,"threadB");
threadB.start();
}
運行結果: threadA—0
threadA—1
threadA—2
threadA—3
threadA—4
threadA—5
threadA—6
threadA—7
threadA—8
threadA—9
threadB—0
threadB—1
threadB—2
threadB—3
threadB—4
threadB—5
threadB—6
threadB—7
threadB—8
threadB—9
小結:當對代碼塊進行加鎖時,當加鎖對象是一個確定值時(當前類,或者已賦值的變量) 不同線程訪問同一個類的不同對象時也可以實現線程同步
最后奉上線程鎖在實際開發(fā)中的應用—-單例模式
1,懶漢式寫法
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2,懶漢式寫法升級版(雙重校驗鎖) 性能優(yōu)于第一種
public?class?Singleton?{
private?static?Singleton?singleton;
private?Singleton?(){}
public?static?Singleton?getSingleton()?{
if?(singleton?==?null)?{
synchronized?(Singleton.class)?{
if?(singleton?==?null)?{
singleton?=?new?Singleton();
}
}
}
return?singleton;
}
}
3,餓漢式寫法,不依賴于線程同步鎖,依賴于靜態(tài)變量和類的同步加載實現線程安全
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
總結
以上是生活随笔為你收集整理的java同步锁如何使用_java 同步锁(synchronized)的正确使用姿势的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 转jsp_【转】JSP三种页面
- 下一篇: java中初始化的顺序_Java中 初始