java非同步存儲
❶ java非同步是什麼意思
java非同步是指程序執行過程中可以不按照指定的順序執行,而是在執行耗時操作時,將其放在另一個線程中運行,同時主線程可以繼續執行其他任務。Java非同步編程可以提高程序的並發性能,避免了一些不必要的線程等待,以及防止UI卡死的情況發生。
Java非同步編程可以使用多線程、Future、CompletableFuture、Callback等方式實現。其中,Future和CompletableFuture是Java中常用的非同步編程方式。Future是Java8之前的非同步實現方式,可以通過get()方法來獲取非同步操作的結果。而CompletableFuture是Java8中的新特性,支持更加復雜的非同步編程場景,可以將多個非同步操作串聯到一起,實現更加復雜的任務。
非同步編程涉及到多線程操作,需要注意線程安全問題。在多線程環境中,尤其是在對共享資源進行操作時,需要使用線程安全的方式來訪問這些資源。Java提供了一些線程安全的類來保證多線程並發時的數據安全,如ConcurrentHashMap、CopyOnWriteArrayList、AtomicInteger等。在使用非同步編程時,必須注意線程安全問題,防止出現數據競爭等問題。
❷ java 中非同步保存數據問題
用ajax非同步提交數據時,後台代碼處理完畢後才會調用回調函數。響應結果給用戶。而在等待響應結果過程中用戶可以進行其它操作,這就是非同步。根據你的問題,如果回調函數被調用了,說明後台處理完成了,也就是保存成功了。沒有響應則反之
❸ java中使用非同步線程池有什麼優缺點
缺點是難以保證數據的准確性 (data integration),還有一個是需要更多的資源。
優點是可以並列處理一些工作,從而減少一些不必要的等待時間(blocking)
非同步線程在 UI 和 網路連接方面很常見的
❹ java非同步處理數據時時數據還沒存到庫里
這是正常的,非同步處理都是這有問題。特別是資料庫開啟事務的時候,上一個線程還沒有提交的話,其他事務是看不到數據的。解決的辦法就是要麼採用同步的機制,在同一個線程中處理數據,自然就不會存在這種問題。如果一定要用非同步的話,可以加入等待機制,就是判斷數據是否入庫,沒有點話就等待一會兒,然後在判斷,直到入庫才進行後續的處理
❺ Java中的線程同步與非同步如何理解
線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。
另外,線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以並發執行。由於線程之間的相互制約,致使線程在運行中呈現出間斷性。線程也有就緒、阻塞和運行三種基本狀態。
就緒狀態是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態是指線程佔有處理機正在運行;阻塞狀態是指線程在等待一個事件(如某個信號量),邏輯上不可執行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位指運行中的程序的調度單位。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。
同步就是只能A走完某一段然後停下,讓B開始走一段再停下,再讓A走。。如此往復。簡單理解就是,必須是一段程序執行完後才能執行後面的程序。。
非同步就是,同一時間可能A和B同時都在往終點趕,此時不存在先後順序,就是說,兩個程序可以同時執行,稱為非同步。
❻ java同步和非同步的區別
java同步和非同步的區別如下:
一、根據情況需要專門的線程方式
如果數據將在線程間共享.例如正在寫的數據以後可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取.
當應用程序在對象上調用了一個需要花費很長時間來執行的方法,並且不希望讓程序等待方法的返回時,就應該使用非同步編程,在很多情況下採用非同步途徑往往更有效率.
二、應用不同:
Java同步:
基本概念:每個Object都會有1個鎖.同步就是串列使用一些資源.
(說明:以下有些例子為了突出重點,省略了不必要的代碼.非凡是省掉了一些成員變數,就是需要同步的對象.)
1. 多線程中對共享、可變的數據進行同步.
對於函數中的局部變數沒必要進行同步.
對於不可變數據,也沒必要進行同步.
多線程中訪問共享可變數據才有必要.
2. 單個線程中可以使用synchronized,而且可以嵌套,但無意義.
class Test {
public static void main(String[] args) {
Test t = new Test();
synchronized(t) {
synchronized(t) {
System.out.println("ok!");
}
}
}
}
3. 對象實例的鎖
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個實列(this)的鎖.
比如: Test t = new Test();
線程A調用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結束.
作用: 多線程中訪問Test的同一個實例的同步方法時會進行同步.
4. class的鎖
class Test{
final static Object o= new Object();
public static synchronized void f1(){
//do something here
}
public static void f2(){
synchronized(Test.class){
//do something here
}
}
public static void f3(){
try {
synchronized (Class.forName("Test")) {
//do something here
}
}
catch (ClassNotFoundException ex) {
}
}
public static void g(){
synchronized(o){
//do something here
}
}
}
上面f1(),f2(),f3(),g()效果一致
f1(),f2(),f3()中synchronized取得的鎖都是Test.class的鎖.
g()是自己產生一個對象o,利用o的鎖做同步
作用: 多線程中訪問此類或此類任一個實例的同步方法時都會同步. singleton模式lazily initializing屬於此類.
5. static method
class Test{
private static int v = 0;
public static void f1(){
//do something, 但函數中沒用用到v
}
public synchronized static void f2(){
//do something, 函數中對v進行了讀/寫.
}
}
多線程中使用Test的某個實列時,
(1) f1()是線程安全的,不需要同步
(2) f2()這個靜態方法中使用了函數外靜態變數,所以需要同步.
Java非同步:
1、 它要能適應不同類型的請求:
本節用 makeString來說明要求有返回值的請求.用displayString來說明不需要返回值的請求.
2、 要能同時並發處理多個請求,並能按一定機制調度:
本節將用一個隊列來存放請求,所以只能按FIFO機制調度,你可以改用LinkedList,就可以簡單實現一個優先順序(優先順序高的addFirst,低的addLast).
3、有能力將調用的邊界從線程擴展到機器間(RMI)
4、分離過度耦合,如分離調用句柄(取貨憑證)和真實數據的實現.分離調用和執行的過程,可以盡快地將調返回.
現在看具體的實現:
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
這個介面有兩個方法要實現,就是有返回值的調用resultTest和不需要返回值的調用
noResultTest, 我們把這個介面用一個代理類來實現,目的是將方法調用轉化為對象,這樣就可以將多個請求(多個方法調)放到一個容器中緩存起來,然後統一處理,因為 Java不支持方法指針,所以把方法調用轉換為對象,然後在這個對象上統一執行它們的方法,不僅可以做到非同步處理,而且可以將代表方法調用的請求對象序列化後通過網路傳遞到另一個機器上執行(RMI).這也是Java回調機制最有力的實現.
一個簡單的例子.
如果 1: 做A
如果 2: 做B
如果 3: 做C
如果有1000個情況,你不至於用1000個case吧?以後再增加呢?
所以如果C/C++程序員,會這樣實現: (c和c++定義結構不同)
type define struct MyStruct{
int mark;
(*fn) ();
} MyList;
然後你可以聲明這個結構數據:
{1,A,
2,B
3,C
}
做一個循環:
for(i=0;i<length;i++) {
if(數據組[i].mark == 傳入的值) (數據組[i].*fn)();
}
簡單說c/c++中將要被調用的涵數可以被保存起來,然後去訪問,調用,而Java中,我們無法將一個方法保存,除了直接調用,所以將要調用的方法用子類來實現,然後把這些子類實例保存起來,然後在這些子類的實現上調用方法:
interface My{
void test();
}