日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java中同步_在Java中的方法同步和语句同步(块同步) - Break易站

發布時間:2024/6/1 java 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中同步_在Java中的方法同步和语句同步(块同步) - Break易站 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 多線程

線程主要通過共享對字段的訪問和參考字段引用的對象進行通信。這種通信形式非常有效,但可能出現兩種錯誤:線程干擾和內存一致性錯誤。需要一些同步構造來防止這些錯誤。以下示例顯示了我們需要同步的情況。

在Java中需要同步的情況

請考慮以下示例:

// Java program to illustrate need

// of Synchronization

import java.io.*;

class Multithread

{

private int i = 0;

public void increment()

{

i++;

}

public int getValue()

{

return i;

}

}

class GfG

{

public static void main (String[] args)

{

Multithread t = new Multithread();

t.increment();

System.out.println(t.getValue());

}

}

輸出:

1

在上面的示例中,執行了三個操作:

獲取變量i的值。

增加獲取的值。

并將增加的i值存儲到其位置。

這里,

第一個線程獲取i的值。(當前值i為0)并將其增加1,因此變量i的值變為1。

現在第二個線程訪問i的值為0,因為第一個線程沒有將它存儲回它的位置。

第二個線程也會增加它并將其存儲回其位置。第1個也存儲它。

最后,變量i的值為1.但是兩個線程的效果應該是2。這就是為什么我們需要同步對共享變量i的訪問。

Java是多線程語言,其中多個線程并行運行以完成其執行。我們需要同步共享資源以確保一次只有一個線程能夠訪問共享資源。

如果一個Object由多個線程共享,則需要進行同步以避免Object的狀態被破壞。當Object是可變的時,需要同步。如果共享Object是不可變的,或者共享同一個Object的所有線程只讀取未修改的Object狀態,則不需要同步它。

Java編程語言提供兩種同步習語:

方法同步

語句同步(塊同步)

Java中的方法同步

同步方法支持一種簡單的策略來防止線程干擾和內存一致性錯誤。如果一個Object對多個線程可見,則對該Object的所有字段的讀取或寫入都是通過synchronized方法完成的。

兩次調用同步方法不可能進行交錯。如果一個線程正在執行synchronized方法,那么在同一個Object上調用synchronized方法的所有其他線程都必須等到第一個線程完成Object。

示例:這顯示了多個線程是否在沒有同步的情況下訪問getLine()方法。

// Example illustrates multiple threads are executing

// on the same Object at same time without synchronization.

import java.io.*;

class Line

{

// if multiple threads(trains) will try to

// access this unsynchronized method,

// they all will get it. So there is chance

// that Object's? state will be corrupted.

public void getLine()

{

for (int i = 0; i < 3; i++)

{

System.out.println(i);

try

{

Thread.sleep(400);

}

catch (Exception e)

{

System.out.println(e);

}

}

}

}

class Train extends Thread

{

// reference to Line's Object.

Line line;

Train(Line line)

{

this.line = line;

}

@Override

public void run()

{

line.getLine();

}

}

class GFG

{

public static void main(String[] args)

{

// Object of Line class that is shared

// among the threads.

Line obj = new Line();

// creating the threads that are

// sharing the same Object.

Train train1 = new Train(obj);

Train train2 = new Train(obj);

// threads start their execution.

train1.start();

train2.start();

}

}

輸出:

0

0

1

1

2

2

可能有兩列火車(兩個以上)需要同時使用,因此有可能發生碰撞。因此,為了避免碰撞,我們需要同步多個想要運行的行。

示例:對同一對象的getLine()方法的同步訪問

// Example that shows multiple threads

// can execute the same method but in

// synchronized way.

class Line

{

// if multiple threads(trains) trying to access

// this synchronized method on the same Object

// but only one thread will be able

// to execute it at a time.

synchronized public void getLine()

{

for (int i = 0; i < 3; i++)

{

System.out.println(i);

try

{

Thread.sleep(400);

}

catch (Exception e)

{

System.out.println(e);

}

}

}

}

class Train extends Thread

{

// Reference variable of type Line.

Line line;

Train(Line line)

{

this.line = line;

}

@Override

public void run()

{

line.getLine();

}

}

class GFG

{

public static void main(String[] args)

{

Line obj = new Line();

// we are creating two threads which share

// same Object.

Train train1 = new Train(obj);

Train train2 = new Train(obj);

// both threads start executing .

train1.start();

train2.start();

}

}

輸出:

0

1

2

0

1

2

Java中的塊同步

如果我們只需要執行一些后續代碼行而不是方法中代碼的所有行(指令),那么我們應該只同步存在所需指令的代碼塊。

例如,假設有一個方法包含100行代碼,但只有10行代碼(一個接一個)包含代碼的關鍵部分,即這些行可以修改(更改)Object的狀態。因此,我們只需要同步這10行代碼方法,以避免對Object狀態進行任何修改,并確保其他線程可以在同一方法中執行其余行而不會中斷。

import java.io.*;

import java.util.*;

public class Geek

{

String name = "";

public int count = 0;

public void geekName(String geek, List list)

{

// Only one thread is permitted

// to change geek's name at a time.

synchronized(this)

{

name = geek;

count++;? // how many threads change geek's name.

}

// All other threads are permitted

// to add geek name into list.

list.add(geek);

}

}

class GFG

{

public static void main (String[] args)

{

Geek gk = new Geek();

List list = new ArrayList();

gk.geekName("mohit", list);

System.out.println(gk.name);

}

}

輸出:

1

重點:

當線程進入同步方法或塊時,它獲取鎖定,一旦完成任務并從synchronized方法退出,它就會釋放鎖定。

當線程進入同步實例方法或塊時,它獲取對象級別鎖定,當它進入同步靜態方法或塊時,它獲取類級別鎖定。

如果在synchronized塊中使用的Object為null,則Java同步將拋出空指針異常。例如,如果在synchronized(實例)中,instance為null,則它將拋出空指針異常。

在Java中,wait(),notify()和notifyAll()是同步中使用的重要方法。

您不能將java?synchronized關鍵字應用于變量。

不要在同步塊上的非final字段上進行同步,因為對非final字段的引用可能隨時更改,然后不同的線程可能在不同的對象上同步,即根本不同步。

優點

多線程:由于java是多線程語言,因此同步是實現共享資源互斥的好方法。

實例和靜態方法:同步實例方法和同步靜態方法都可以同時執行,因為它們用于鎖定不同的對象。

限制

并發限制:?Java同步不允許并發讀取。

降低效率:?Java同步方法運行速度非常慢并且會降低性能,因此您應該在絕對必要時同步方法,否則不要同步塊僅用于代碼的關鍵部分。

總結

以上是生活随笔為你收集整理的java中同步_在Java中的方法同步和语句同步(块同步) - Break易站的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。