Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

Çıkış Yap

translation

Bu, AI tarafından çevrilen bir gönderidir.

제이온

[Java] Senkronize Edilmiş Koleksiyonlar vs Eşzamanlı Koleksiyonlar

  • tr Writing language: Korece
  • tr Referans Ülke: tr Tüm ülkeler country-flag

Dil Seç

  • Türkçe
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

Text summarized by durumis AI

  • Vector, Hashtable, Collections.synchronizedXXX gibi senkronize edilmiş koleksiyonlar, içsel olarak synchronized anahtar sözcüğünü kullanarak eşzamanlılığı sağlar, ancak birden fazla işlemi bir araya getirerek kullanmak veya performans düşüşü sorunları ortaya çıkabilir.
  • java.util.concurrent paketinde sağlanan eşzamanlı koleksiyonlar, CopyOnWriteArrayList, ConcurrentMap, ConcurrentHashMap gibi çeşitli sınıflar sunar ve senkronize edilmiş koleksiyonlardan daha yüksek performansa sahiptir.
  • CopyOnWriteArrayList, ConcurrentHashMap gibi eşzamanlı koleksiyonlar, senkronize edilmiş koleksiyonlara göre daha yüksek okuma performansına sahiptir ve yazma işlemleri nispeten az olduğunda kullanılması etkilidir.

Senkronize Edilmiş Koleksiyonlar

Senkronize edilmiş koleksiyonlar, öncelikle aşağıdaki gibi sınıfları içerir.


  • Vector
  • Hashtable
  • Collections.synchronizedXXX


Bu sınıfların hepsi, içerideki değerleri yalnızca bir iş parçacığının kullanabileceği şekilde kontrol ederek ve aynı zamanda eşzamanlılığı sağlayarak, genel olarak ilan edilmiş yöntemlerde synchronized anahtar sözcüğünü kullanır.


Vector

public class Vector extends AbstractList
    implements List, RandomAccess, Cloneable, java.io.Serializable {
    ...
    public synchronized boolean add(E e) {
                modCount++;
                add(e, elementData, elementCount);
                return true;
    }
    ...

Vector sınıfında eleman ekleyen add() yöntemini incelediğimizde synchronized anahtar sözcüğünü görürüz. Yani, Vector içinde eleman ekleme işlemi gerçekleştiğinde eşzamanlılık sağlanır.

Hashtable

public class Hashtable extends Dictionary
    implements Map, Cloneable, java.io.Serializable {
        ...
        public synchronized boolean contains(Object value) {
        if (value == null) {
            throw new NullPointerException();
        }

        Entry tab[] = table;
        for (int i = tab.length ; i-- > 0 ;) {
            for (Entry e = tab[i] ; e != null ; e = e.next) {
                if (e.value.equals(value)) {
                    return true;
                }
            }
        }
        return false;
    }
        ...


Hashtable sınıfında aynı değerin olup olmadığını kontrol eden contains() yöntemini incelediğimizde, Vector sınıfında olduğu gibi synchronized anahtar sözcüğünün kullanıldığını görürüz.


Collections.synchronizedXXX

Collections.synchronizedList() yöntemi kullanılarak oluşturulan SynchronizedList sınıfını inceleyelim.


static class SynchronizedList extends SynchronizedCollection
        implements List {

        final Object mutex;

        ...
        public E get(int index) {
                synchronized (mutex) {return list.get(index);}
        }

        public E set(int index, E element) {
                synchronized (mutex) {return list.set(index, element);}
        }

        public void add(int index, E element) {
                synchronized (mutex) {list.add(index, element);}
        }

        public E remove(int index) {
                synchronized (mutex) {return list.remove(index);}
        }
        ...


SynchronizedList sınıfının yöntemlerini incelediğimizde hepsinde synchronized anahtar sözcüğünün kullanıldığını görürüz. Ancak eşzamanlılığı sağlamak için mutex aracılığıyla synchronized bloğu kullanılmıştır. Tüm yöntemler mutex objesini paylaşır, bu nedenle bir iş parçacığı synchronized bloğuna girdiği anda, diğer yöntemlerin synchronized bloğu da kilitlenir.


Senkronize Edilmiş Koleksiyonların Sorunları

Çoklu iş parçacığı ortamında senkronize edilmiş koleksiyonlar kullanılması gereken durumlar da olsa, mümkün olduğunca başka eşzamanlılık yöntemleri kullanmak daha iyidir. Bunun nedeni, esas olarak iki ana nedene dayanır.


Birkaç işlemi tek işlem gibi kullanma

Senkronize edilmiş koleksiyon sınıfları, çoklu iş parçacığı ortamında eşzamanlılığı sağlar. Ancak, birkaç işlemi tek işlem gibi kullanmak gerekiyorsa sorunlar ortaya çıkar. Bu senkronize edilmiş koleksiyonları kullanmaya rağmen doğru şekilde çalışmayabilir.


final List list = Collections.synchronizedList(new ArrayList());
final int nThreads = 2;
ExecutorService es = Executors.newFixedThreadPool(nThreads);

for (int i = 0; i < nThreads; i++) {
    es.execute(new Runnable() {

        public void run() {
            while(true) {
                try {
                    list.clear();
                    list.add("888");
                    list.remove(0);
                } catch(IndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
            }
        }
    });


Yukarıdaki kod çalıştırıldığında, Thread A remove(0) işlemini yaparken Thread B clear() işlemini yaparsa hata oluşur. Bu nedenle aşağıdaki gibi bir synchronized bloğu içinde gruplanmalıdır.


synchronized (list) {
    list.clear();
    list.add("888");
    list.remove(0);


Performans Düşüşü

Paylaşılan nesneyi kullanmak isteyen tüm yöntemleri synchronized yöntemler yaparsanız veya yöntemlerin içinde aynı synchronized bloğu tanımlarsanız, bir iş parçacığı kilidi elde ettiği anda diğer iş parçacıkları tüm senkronize edilmiş yöntemleri kullanamaz ve engelleyici durumda olur. Bu tekrarlanan durum, performans düşüşüne neden olabilir.


Eşzamanlı Koleksiyonlar

java.util.concurrent paketinde sunulan paralel koleksiyon türleri aşağıdaki gibidir ve bunlardan yalnızca bazıları bu makalede ele alınacaktır.


  • CopyOnWriteArrayList
    • List sınıfının alt sınıfıdır ve nesne listesini yineleyerek sorgulama işlemlerinin performansını önceliklendiren bir paralel koleksiyondur.
  • ConcurrentMap
    • Paralel bir koleksiyondur ve arayüzü, eklenmek istenen öğenin daha önce yoksa yalnızca eklenmesini sağlayan put-if-absent, replace, conditional remove işlemleri gibi yöntemleri tanımlar.
  • ConcurrentHashMap
    • ConcurrentMap'in alt sınıfıdır ve HashMap'in yerine geçerek paralelliği sağlayan paralel bir koleksiyondur.
  • ConcurrentLinkedQueue
    • FIFO yöntemini kullanan bir Queue'dur ve paralelliği sağlayan bir paralel koleksiyondur. Kuyrukta çıkarılacak öğe yoksa, derhal döndürür ve başka bir işlemi yürütmeye gider.
  • LinkedBlockingQueue
    • ConcurrentLinkedQueue'a benzer. Ancak kuyruk boşsa kuyruktan öğe çıkarma işlemi, yeni öğe eklenene kadar bekler. Tersine, kuyruğa boyut verilmişse ve kuyruk belirtilen boyuta kadar doluysa, kuyruğa yeni öğe ekleme işlemi kuyrukta boş yer olana kadar bekler.
  • ConcurrentSkipListMap, ConcurrentSkipListSet
    • Sırasıyla SortedMap ve SortedSet sınıflarının paralelliğini artıran gelişmiş biçimleridir.


Daha önce kullanılan senkronize edilmiş koleksiyon sınıflarını paralel koleksiyonlarla değiştirmek bile, başka risk faktörleri olmadan genel performansı önemli ölçüde artırabilir.

Paralel koleksiyonlara karşıt olan senkronize edilmiş koleksiyonları karşılaştırarak ayrıntılı olarak inceleyelim.


CopyOnWriteArrayList

Senkronize edilmiş bir ArrayList oluşturmanın iki yolu vardır.


  • Collections.synchronizedList()
  • CopyOnWriteArrayList


Collections.synchronizedList() JDK 1.2 sürümüne eklenmiştir. Bu koleksiyon, tüm okuma ve yazma işlemleri için senkronize edilmiştir, bu nedenle esnek olmayan bir tasarım olarak kabul edilebilir. Bu nedenle, CopyOnWriteArrayList ortaya çıkmıştır.


Okuma İşlemleri

SynchronizedList, okuma ve yazma işlemleri sırasında kendi kendine kilitlenir. Ancak CopyOnWriteArrayList, tüm yazma işlemleri sırasında orijinal dizideki elemanları kopyalayarak yeni bir geçici dizi oluşturur ve bu geçici dizide yazma işlemini gerçekleştirdikten sonra orijinal diziyi günceller. Bunun sayesinde okuma işlemleri kilitlenmez, bu nedenle SynchronizedList'ten daha iyi performansa sahiptir.


public class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable {

    final transient Object lock = new Object();
    private transient volatile Object[] array;

        ...
        public E get(int index) {
        return elementAt(getArray(), index);
    }
        ...


Yukarıda get() yöntemi yer almaktadır ve synchronized olmadığı için kilitlenmemektedir.


Yazma İşlemleri

CopyOnWriteArrayList, yazma işlemi gerçekleştirirken açıkça kilit kullanır. Sonuç olarak, her iki koleksiyon türü de bu işlemde kilitlenir. Bu durumda CopyOnWriteArrayList, nispeten maliyetli dizi kopyalama işlemini gerçekleştirir, bu nedenle önemli sayıda yazma işlemi gerçekleştirilirse performans sorunları ortaya çıkabilir.


public class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable {

    final transient Object lock = new Object();
    private transient volatile Object[] array;

        public void add(int index, E element) {
        synchronized (lock) {
            ...
            int numMoved = len - index;
            if (numMoved == 0)
                newElements = Arrays.copyOf(es, len + 1);
            else {
                newElements = new Object[len + 1];
                System.arraycopy(es, 0, newElements, 0, index);
                System.arraycopy(es, index, newElements, index + 1,
                                 numMoved);
            }
                        ...
        }
    }


Yukarıda add() yöntemi yer almaktadır ve synchronized bloğu aracılığıyla kilitlenir ve dizi kopyalama işlemi gerçekleştirilir.


Iterator

CopyOnWriteArrayList'te yineleyiciyi çıkarma anındaki koleksiyon verilerine göre yineleme yapılır ve yineleme sırasında koleksiyona veri eklenmesi veya silinmesi, yineleme döngüsüyle ilgili olmayan bir kopya üzerinde yansıtılır, bu nedenle eşzamanlı kullanımlarda sorun yaşanmaz.


CopyOnWriteArraySet

Senkronize edilmiş bir Set oluşturmanın iki yolu vardır.


  • Collections.synchronizedSet()
  • CopyOnWriteArraySet


Yöntem adından da anlaşılacağı gibi, CopyOnWriteArrayList ile çalışma yöntemi, veri yapısı özelliği hariç, neredeyse aynıdır.


Okuma İşlemleri

public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable {

    private final CopyOnWriteArrayList al;

        public boolean contains(Object o) {
        return al.contains(o);
    }


Yukarıda contains() yöntemi yer almaktadır ve CopyOnWriteArraySet'in içeride CopyOnWriteArrayList'i tanımladığını ve CopyOnWriteArrayList'in yöntemlerini kullandığını görebiliriz.


public boolean contains(Object o) {
        return indexOf(o) >= 0;
}

public int indexOf(Object o) {
        Object[] es = getArray();
        return indexOfRange(o, es, 0, es.length);
}

    private static int indexOfRange(Object o, Object[] es, int from, int to) {
        if (o == null) {
            for (int i = from; i < to; i++)
                if (es[i] == null)
                    return i;
        } else {
            for (int i = from; i < to; i++)
                if (o.equals(es[i]))
                    return i;
        }
        return -1;


CopyOnWriteArrayList'in contains() yöntemini incelediğimizde, kilitlenmediğini görebiliriz.


Yazma İşlemleri

public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable {

        private final CopyOnWriteArrayList al;

        public boolean add(E e) {
        return al.addIfAbsent(e);
    }


add() yöntemi de CopyOnWriteArrayList'in yöntemlerini kullanır.


public boolean addIfAbsent(E e) {
    Object[] snapshot = getArray();
    return indexOfRange(e, snapshot, 0, snapshot.length) < 0
        && addIfAbsent(e, snapshot);
}

private boolean addIfAbsent(E e, Object[] snapshot) {
        synchronized (lock) {
            Object[] current = getArray();
            int len = current.length;
            if (snapshot != current) {
                // Optimize for lost race to another addXXX operation
                int common = Math.min(snapshot.length, len);
                for (int i = 0; i < common; i++)
                    if (current[i] != snapshot[i]
                        && Objects.equals(e, current[i]))
                        return false;
                if (indexOfRange(e, current, common, len) >= 0)
                        return false;
            }
            Object[] newElements = Arrays.copyOf(current, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        }


addIfAbsent() yöntemini incelediğimizde, yazma işlemi gerçekleştirirken kilitlendiğini ve dizi kopyalama işleminin gerçekleştiğini görürüz. Bu nedenle, CopyOnWriteArraySet de CopyOnWriteArrayList gibi, çok sayıda yazma işlemi yapmaktan kaçınmak daha iyidir.


ConcurrentHashMap

Senkronize edilmiş bir HashMap oluşturmanın iki yolu vardır.


  • Collections.synchronizedMap(new HashMap<>())
  • ConcurrentHashMap


ConcurrentHashMap, HashMap ile aynı şekilde Hash tabanlı bir Map'tir. synchronizedMap'e göre daha etkili bir şekilde eşzamanlılığı sağlar.


Java 8'den önce, ReentrantLock'tan kalıtım alan Segment'leri kullanarak, bölgeleri ayırarak bölge bazlı kilitleme gerçekleştiriliyordu.


Java 8'den sonra, her bir tablo kovasını bağımsız olarak kilitleme yöntemi kullanılmaktadır. Boş bir kovaya düğüm eklenmesi durumunda, kilit yerine CAS algoritması kullanılır ve diğer değişiklikler, her bir kovadaki ilk düğümü temel alarak kısmi kilit (synchronized block) elde edilerek iş parçacığı çatışması en aza indirilir ve eşzamanlılık sağlanır.


ConcurrentHashMap'e yeni bir düğüm ekleyen putVal() yönteminin kodunu inceleyerek eşzamanlılığın nasıl sağlandığını görelim. Dikkat çekmek gerekirse, aşağıdaki örnek kod Java 11 tabanlıdır.


putVal() yöntemi, temel olarak aşağıdaki iki duruma (toplam dört bölümde şube) ayrılabilir.


  • Boş bir hash kovasına düğüm ekleme
  • Hash kovasında zaten düğüm varsa


final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node[] tab = table;;) {
            Node f; int n, i, fh; K fk; V fv;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
                        // (1)
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                                // (2)
                if (casTabAt(tab, i, null, new Node(hash, key, value)))
                    break;
            }
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            else if (onlyIfAbsent // check first node without acquiring lock
                     && fh == hash
                     && ((fk = f.key) == key || (fk != null && key.equals(fk)))
                     && (fv = f.val) != null)
                return fv;
                        // (3)
            else {
                V oldVal = null;
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node e = f;; ++binCount) {
                                K ek;
                                                                // (4)
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node pred = e;
                                                                // (5)
                                if ((e = e.next) == null) {
                                    pred.next = new Node(hash, key, value);
                                    break;
                                }
                            }
                        }
                                                // (6)
                        else if (f instanceof TreeBin) {
                            Node p;
                            binCount = 2;
                            if ((p = ((TreeBin)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                        else if (f instanceof ReservationNode)
                            throw new IllegalStateException("Recursive update");
                    }
                }
                                ...
            }
        }
                ...


Boş bir hash kovasına düğüm ekleme

(1) Yeni bir düğüm eklemek için, ilgili kovanın değerini (tabAt()) alır ve boş olup olmadığını kontrol eder.


static final  Node tabAt(Node[] tab, int i) {
        return (Node)U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE);


(2) Düğümde bulunan volatile değişkene erişerek, mevcut değerle (null) karşılaştırılır ve aynıysa yeni düğüm kaydedilir. Aynı değilse, for döngüsü tekrarlanır. Bu yöntem CAS algoritmasıdır.


static final  boolean casTabAt(Node[] tab, int i, Node c, Node v) {
        return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v);


CAS algoritması kullanılarak atomicity ve görünürlük sorunları çözülür ve eşzamanlılık sağlanır.


Hash kovasında zaten düğüm varsa

(3) Zaten düğüm varsa, synchronized block kullanılarak yalnızca bir iş parçacığının erişmesi sağlanır. Bu durumda, boş olmayan Node tipindeki hash kovasına kilitlendiğinden, aynı kovaya erişen iş parçacıkları engelleyici durumda olur.

(4) Yeni düğümle değiştirilir.

(5) Hash çakışması meydana gelirse, Ayrı Bağlamaya eklenir.

(6) Hash çakışması meydana gelirse, ağaca eklenir.


Referanslar


Beklenen Görüşme Soruları ve Cevapları

Vector, HashTable ve Collections.SynchronziedXXX'in sorunları nelerdir?

Vector, HashTable ve SynchronziedXxx sınıfları synchronized yöntemler veya bloklar kullanır ve aynı kilidi paylaşır. Bu nedenle, koleksiyonlara bir iş parçacığı tarafından kilit elde edilirse, diğer iş parçacıkları tüm yöntemleri kullanamıyor ve engelleyici durumda kalıyor. Bu da uygulama performansında düşüşe neden olabilir.


SynchronizedList ve CopyOnArrayList arasındaki farklar nelerdir?

SynchronizedList, okuma ve yazma işlemleri sırasında kendi kendine kilitlenir. Ancak CopyOnArrayList, yazma işlemi sırasında ilgili bloğu kilitler ve orijinal dizideki elemanları kopyalayarak yeni bir geçici dizi oluşturur ve bu geçici dizide yazma işlemini gerçekleştirdikten sonra orijinal diziyi günceller. Bunun sayesinde okuma işlemleri kilitlenmez, bu nedenle SynchronizedList'ten daha iyi okuma performansına sahiptir. Ancak yazma işlemleri, nispeten maliyetli dizi kopyalama işlemini gerçekleştirdiği için SynchronizedList'ten daha düşük yazma performansına sahiptir.

Bu nedenle, değişiklik yapma işlemlerinden çok okuma işlemi yapılıyorsa, CopyOnArrayList kullanmak daha etkilidir.


SynchronizedMap ve ConcurrentHashMap arasındaki farklar nelerdir?

SynchronziedMap, okuma ve yazma işlemleri sırasında kendi kendine kilitlenir. Ancak ConcurrentHashMap, her bir tablo kovasını bağımsız olarak kilitleme yöntemi kullanır. Örneğin, boş bir kovaya düğüm eklenmesi durumunda kilit (Lock) yerine CAS algoritması kullanılır ve diğer değişiklikler, erişilen kovaya yalnızca kilitlenerek iş parçacığı çatışması en aza indirilir ve eşzamanlılık sağlanır.

제이온
제이온
제이온
제이온
[Spring] @Async kullanımı Spring @Async'yi kullanarak Java eşzamansız işlemlerini kolayca uygulamanın yollarını öğrenin. @Async anotasyonu ile senkron metotları eşzamansız hale getirebilir ve iş parçacığı havuzu ayarlarıyla verimliliği artırabilirsiniz. Future, ListenableFuture ve

25 Nisan 2024

[Efektif Java] Madde 6: Gereksiz Nesne Oluşturmayı Önleyin Java'da gereksiz nesne oluşturmayı azaltma yöntemleri hakkında bir kılavuz. String, Boolean gibi değişmez nesneler için literalleri kullanın ve düzenli ifadeler için Pattern örneklerini önbelleğe alın. Ayrıca, otomatik kutulama performans düşüşüne neden o

28 Nisan 2024

Java Collections Framework (JCF) nedir? - JCF'nin tanımı ve özellikleri (JAVA) Java Collections Framework (JCF), birden fazla veriyi verimli bir şekilde işlemek için standartlaştırılmış bir yöntem sağlayan bir Java sınıf koleksiyonudur. JCF, veri depolama yapıları ve algoritmaları sınıflar halinde uygulayarak kod tekrar kullanılabil

27 Nisan 2024

[Eşzamanlılık] Atomik İşlem: Bellek Çiti ve Bellek Sıralaması Bu blog yazısında, atomik işlemlerde bellek sıralamasının nasıl dikkate alınacağı ve Sıralama seçeneklerinin önemi açıklanmaktadır. Relaxed, Acquire, Release, AcqRel, SecCst gibi çeşitli Sıralama seçenekleri hakkında açıklamaların yanı sıra, her seçeneğin
곽경직
곽경직
곽경직
곽경직
곽경직

12 Nisan 2024

[Bilişim alanında olmayanlar için, geliştirici olarak hayatta kalmak] 14. Yeni Başlayan Geliştiricilerin Sıkça Sorduğu Teknoloji Görüşme İçerikleri Özeti Yeni başlayan geliştiriciler için bir teknoloji görüşme hazırlık rehberidir. Ana bellek alanı, veri yapıları, RDBMS ve NoSQL, yordamsal ve nesne yönelimli, geçersiz kılma ve aşırı yükleme, sayfa değiştirme algoritmaları, süreçler ve iş parçacıkları, OSI 7
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 Nisan 2024

Rust'ın Eşzamanlılık Hatalarını Önleme Yolu Rust, eşzamanlı programlamanın zorluklarını aşmak için güçlü bir dildir. Tip sistemi ve sahiplik modeli sayesinde, iş parçacıkları arasında veri aktarımı ve paylaşımı güvenlidir. Mutex, Channel, Atomic gibi iç değişkenlik kalıpları ile paylaşılan değişken
곽경직
곽경직
곽경직
곽경직
곽경직

28 Mart 2024

[Javascript] Nesne Yapısı (V8) JavaScript'teki Nesne, V8 motorunda durumuna göre yapı gibi optimize edilmiş Hızlı mod ve karma tablo olarak çalışan Sözlük moduna dönüştürülür. Hızlı mod, anahtar ve değerlerin neredeyse sabit olduğu bir biçimde hızlıdır ancak yeni bir anahtar eklendiğin
곽경직
곽경직
곽경직
곽경직
곽경직

18 Mart 2024

Yatırım Metodolojisi (Hisseler) Sonsuz alım yöntemi ve yedili bölme yöntemine dayalı olarak ABD hisse senedi ETF'lerine yatırım stratejisi sunulmaktadır. Hisse senedi seçimi, yatırım tutarının bölünmesi, alım/satım zamanlamasının belirlenmesi, otomatikleştirilmiş işlem sisteminin oluştu
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마

20 Nisan 2024

Otomatik işlem programı geliştirme fikirleri Grid işlem yöntemini otomatikleştiren programın işlevselliğini geliştirme fikirlerini tanıtır ve büyük olay yönetimi, yatırım fonu yönetimi mantığı, kısa pozisyon işlevi ekleme gibi öneriler sunar. Özellikle tutma işlevi aracılığıyla, ani düşüşlerde daha
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마
(로또 사는 아빠) 살림 하는 엄마

21 Nisan 2024