Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - Filip Jirsák

Stran: 1 ... 232 233 [234] 235 236 ... 375
3496
Pokazdy, kdyz ti vyvratim tvoje tvrzeni, tak prijdes s necim jinym.
Tak ta moje pravdivá tvrzení nevyvracejte a já vám pak nebudu muset pomocí dalších tvrzení dokazovat, že jsou pravdivá.

jestli JVM potrebuje singatures (o tom jsme se nebavili).
Ne, o tom jsme se vůbec nebavili, akorát tím celá debata začala, když jsem vám vysvětloval, že kolekce nemůže použít vlastnosti žádného jiného typu, protože za běhu v JVM je v kolekci jenom typ Object.

3497
Ne, neni takhle definovana v bytecode. Je definovana jako
Aha, budeme hrát najdete pět rozdílů. Nebo aspoň jeden:

(Ljava/lang/Object;)Z
(Ljava/lang/Object;)Z

Dulezita je signature.
Ne, není. To je jen doplňková informace pro kompilátor, JVM je to úplně ukradené.

Takze compiler bez zrojaku nevi jak ma nahradit generics? Jak ma delat strong type checking, protoze vsechno je Object? Ta informace neni v bytecode?
Pro nahrazování generik kompilátor ty rozšířené informace nepotřebuje, k tomu mu stačí raw typy. Aby mohl dělat strong type checking, jsou v class souboru doplněné ty typové informace navíc oproti bajtkódu, který zpracovává JVM. V raw typech nemusí být všechno objekt, je tam typ určený omezeními generik. Ty informace v class souboru jsou jako rozšířené atributy, které nepotřebuje JVM – podobně jako třeba ladicí informace (jména lokálních proměnných nebo čísla řádků).

A kolekce na tyhle rozšířené informace opravdu žádným způsobem nespoléhají. Ony kolekce byly součástí Javy už před Javou 5, a tehdy opravdu měly i ve zdrojáku jako parametr napsán typ Object. A protože rozhraní je stále zpětně kompatibilní, mají takový typ i dnešní raw kolekce.

Nechápu, proč si to nezjistíte sám, metodu Class.getMethods() snad znáte, takže všechny metody libovolného typu kolekce si můžete vypsat. Na třídě java.util.Collection těch metod add opravdu moc nenapočítáte, protože tam bude ta jedna jediná, která má jako parametr typ Object.

3498
Do kolekce se nedávají třídy, ale objekty splnující deklarované rozhraní.
Přičemž v JVM v kolekcích z Java Collections Framework je to deklarované rozhraní vždy java.lang.Object. Od Javy 5 výš dělá kompilátor „kouzla“ s generiky, takže ve zdrojovém kódu může být deklarované jiné rozhraní, ale v class file jsou metody kolekcí pořád deklarované jako booleanadd(Object item).

Neni to pravda :) https://docs.oracle.com/javase/10/docs/api/java/util/Collection.html#add(E)

Proč se pouštíte do diskuse o něčem, čemu nerozumíte? Když napíšu, že v Java bytecode je to nějak a Java zdroják nad tím jenom dělá jakási cukrlátka, fakt není dobrý nápad napsat, že to není pravda a dokazovat to odkazem na JavaDoc, který popisuje právě ta cukrlátka v Java zdrojáku. Když se podíváte do bajtkódu, zjistíte, že tam je metoda opravdu definována jako java/util/Collection.add:(Ljava/lang/Object;)Z. A když si nastudujete něco o type erasure, pomocí kterého jsou implementovány generiky v Javě, pochopíte, proč je to tak v bajtcode. A pokud je bajtkód nad vaše síly, zkuste si to alespoň v Javě pomocí reflexe:
Kód: [Vybrat]
Method addMethod = java.util.Collection.class.getMethod("add", Object.class);
Zkuste si tam místo Object.class dát jakoukoli jinou třídu, a uvidíte, zda takové metody existují…

3499
Ne, to neni specialni vlastnost ConcurrentHashMap. To je vlastnost happens-before. Je to i u jinych kolekci, ktery jsou synchronized.
Takže je to speciální vlastnost ConcurrentHashMap jako synchronizované kolekce, jak jsem napsal.

3500
Do kolekce se nedávají třídy, ale objekty splnující deklarované rozhraní.
Přičemž v JVM v kolekcích z Java Collections Framework je to deklarované rozhraní vždy java.lang.Object. Od Javy 5 výš dělá kompilátor „kouzla“ s generiky, takže ve zdrojovém kódu může být deklarované jiné rozhraní, ale v class file jsou metody kolekcí pořád deklarované jako booleanadd(Object item).

3501
Single thread si do toho zamotal ty.
Psal jsem o modifikacích prvků kolekce, které jste do toho zamotal mimo jiné vy. A psal jsem, že se to dělí na dvě varianty. Buď modifikace, které nemají vliv na hashCode() a equals() – takové modifikace kolekci vůbec nezajímají, takže není potřeba řešit žádnou synchronizaci. A nebo modifikace prvku, která má vliv na hashCode() a equals() – taková modifikace by byla pro hashovanou kolekci problém i v jednovláknovém prostředí, takže synchronizace by ničemu nepomohla.

Takze, kdyz nactu z ConcurrentHashMap prvek, zmenim ho a dam ho zpatky (se stejnym klicem), zajistil jsem viditelnost zmen v jinych trehaded nebo ne? Muzu zmenit ten prvek (ne klic)?
Když vložíte do ConcurrentHashMap jinou hodnotu pod původní klíč, bude pod tím klíčem nová hodnota viditelná ze všech vláken. Ale to je speciální vlastnost ConcurrentHashMap, která je speciálně pro konkurenční přístup určená. Pokud jenom změníte nějaké vlastnosti hodnoty, s mapou to vůbec nijak nesouvisí (a pro hodnoty v mapě nejsou důležité ani metody hashCode() a equals()) – pokud se tou hodnotou má pracovat ve více vláknech, musí ty změny být synchronizované. ConcurrentHashMap tomu nijak nepomůže.

Staraji. Kazdy volani zajistuje uplatneni happened-before.
Nestarají. Synchronizovaná jsou pouze volání metod na těch kolekcích. Co se děje s prvky kolekce ty kolekce vůbec nezajímá.

Například v tomhle kódu vám to druhé vlákno může vypsat 0, 1 nebo i hodnotu, kterou měla ta položka ještě dříve.
Kód: [Vybrat]
Item item = synchronizedMap.get("item1");
item.setValue(0);
new Thread(() -> item.setValue(1)).start();
new Thread(() -> System.out.println(item.getValue())).start();

Prave. Kdyz neco pridam do fronty, tak vsechny zmeny udelany predtim (i tech prvku), tak se uplatni.
Což je ale dané tím, jak fungují paměťové bariéry. Není to žádná specialita synchronizovaných kolekcí, protože úplně stejně se to bude chovat i při jakémkoli jiném použití synchronizačních primitiv.

Takhle to nevyznelo. Ale beru opravu.

Mně zase jako pravý opak vyznělo to vaše tvrzení:

Citace: Karel Rank
Jestli se modifikujou elementy kolekce, tak musi byt samozrejme synchronizovany pres stejny monitor.
Proto jsem na to reagoval.

3502
Proc se bavime o single thread?
V té části, kterou jste citoval, se bavíme o multihtread.

Proc by melo dojit k uvaznuti (asi deadlock?)?
Protože se jedním zámkem pokrývají dvě nesouvisející operace. Ale je pravda, že to samo k uváznutí nepovede, k tomu jsou potřeba dva zámky.

Jak todle resi Collections.synchornized*?
Řeší to správně, synchronizují jen kolekce a o jednotlivé prvky kolekcí se nestarají.

Jak happened-before je reseno v SynchronousQueue a Executors Framework?
Pomocí běžných synchronizačních primitiv, které jsou v Javě dostupné.

Ne, do kolekce se nedavaji Object. Davaji se tam jakykoliv tridy.
Ne, do kolekcí se nedávají třídy, dávají se tam instance. Přičemž rozhraní kolekcí vyžaduje, aby to byly instance třídy Object, tedy od těch instancí nemohou vyžadovat žádné zvláštní chování nad rámec třídy Object.

U jakych kolekci je takhle nastavenej konktrakt (ja to vim)?
hashCode() překvapivě u kolekcí, které používají hash objektu, tedy všechny kolekce, které mají v názvu „Hash“, s výjimkou identityHashMap. equals() u všech kolekcí, pokud není řečeno jinak – přičemž pokud vím, jinak je to u kolekcí v JDK pouze (opět) u IdentityHashMap, která používá identitu objektů, nikoli equals().

Takze podle tvoji logiky nesmim menit zadny objekt, ktery je v kolekci? To by bylo asi hodne omezeny pouziti :)
Ne, psal jsem pravý opak, že prvky v kolekci se mohou modifikovat libovolně, pokud to neovlivní hashCode() nebo equals().

3503
Jestli se modifikujou elementy kolekce, tak musi byt samozrejme synchronizovany pres stejny monitor.
Jestli tím myslíte změny vnitřního stavu prvků kolekce, pak to není pravda – právě naopak, takové změny nesmí být synchronizovány přes stejný monitor, mohlo by dojít k uváznutí. Takové změny musejí být synchronizovány s ohledem na to, jak se s těmi objekty pracuje – většinou asi každý prvek bude mít svůj vlastní monitor. Je dokonce možné, že synchronizované vůbec být nemusí – pokud se s každým prvkem té kolekce pracuje jen v jednom vláknu.

Uvědomte si, že do kolekcí se dávají prvky typu Object, je tak nastavený i kontrakt kolekcí. Takže kolekci změny čehokoli, co je mimo Object, nezajímají. V Object je hashCode() a equals(), které pro změnu musí zůstat neměnné po celou dobu existence objektu v kolekci, bez toho by většina kolekcí fungovala špatně – i v jednovláknovém kódu. Nebo-li změny stavu objektu, které by vyvolaly změnu hashCode() nebo equals() by byly špatně i v jednovláknovém kódu a žádná synchronizace tomu nepomůže, a jakékoli jiné změny kolekci nezajímají, nedozví se o nich a tudíž nemusí být kvůli kolekci synchronizovány.

3504
Mate pravdu, ze nemenit nic co by zmenilo hashCode a equals je zaklad. Predpokladal jsem, ze toto neni ten problem, protoze to ze zacatku fungovalo a nahodne se to rozbiji, ale muze to byt i tim, ze kod, ktery meni vnitrni stav objektu byl pridan pozdeji, nebo nebyl pouzivany.
tady ale nebyl problém s prvky té kolekce, ale s tou kolekcí jako takovou.

Ale vzhledem k tomu, že LinkedhashSet je implementováno pomocí HashMap, a HashMap má field int size a metody

Kód: [Vybrat]
public int size() {
  return size;
}

public boolean isEmpty() {
 return size == 0;
}

je jasné, že si HashMapa (logicky) udržuje počet položek nezávisle na skutečném obsahu mapy. A tudíž je zřejmé, že se při nesynchronizovaném přístupu může rozejít stav „počítadla“ size se skutečným stavem mapy. Iterátor pak už samozřejmě musí jít do samotné mapy, kde zjistí, že tam ve skutečnosti nic není. Taky mohl Ondřej  skončit ve stavu, že by mu size() vracelo zápornou hodnotu… isEmpty() by bylo pořád false, a iterátor by klidně mohl nějaké hodnoty vracet.

Mně teda ale hlavně překvapuje, pokud tam Ondřej ty iterátory normálně používá, že to nikdy nevypadlo na ConcurrentModificationException. Že je to jenom taková nouzová pojistka, která ve vícevláknovém prostředí nemusí fungovat správně, je jasné, ale že se to netrefilo nikdy… Předpokládám, že modifikace toho setu probíhala z jiných vláken, než která používala ten iterátor, takže prostě každé vlákno mělo svou lokální hodnotu počtu modifikací a nikdy se to nepotkalo.

3505
Pokud mate synchronizovane oprace nad Set<...> tak to nestaci pokud neco co je v te Set pustite mimo synchronized sekci a pak to tam menite. Musite zajistit, ze se to bud nebude menit - nejlepsi, nebo ze veskere zmeny budou opet synchronizovane.
Pokud ty změny neovlivní hashCode() a equals(), tak je tomu Setu úplně jedno, že se ten objekt mění mimo kód synchronizovaný pro tu práci se Setem. Ostatně, ten Set ani nic jiného než referenci na ten objekt a jeho hash kód nezná. něco jiného je, že je divné v nesynchronizovaném kódu měnit sdílené objekty, pak můžete vidět v každém vlákně jiný stav toho objektu – ale to není problém toho Setu. Ale ty změny klidně mohou být synchronizovány jinak, nezávisle na tom Setu (naopak je to tak správně, synchronizovat se má vždy co nejmenší blok kódu a zamykat co nejméně věcí, a nechcete zbytečně zamykat Set, když plánujete jenom změnit field jedné položky v tom Setu).

A naopak, pokud změny v tom objektu změní hashCode() nebo i jen equals(), pak to chování toho Setu rozbije i v jednovláknovém kódu, se synchronizací to nijak nesouvisí.

Nejjednodussi pravidlo je, ze cokoli je sdilene je immutable a ma to builder.
A nejjednodušší builder je konstruktor a immutable zajistí final fieldy. Pak vám to pohlídá i kompilátor, že ten objekt nejde změnit ani zevnitř.

3506
Co mi ještě není úplně jasné je, čemu se vystavuju, pokud bych vracel ven měnitelné položky toho setu (neobalil je jak uvádí Zdenek Henek)?
To není úplně přesné. Java collections framework má nějaké požadavky na položky, které se do kolekcí vkládají – na hashCode, equals a compare. Respektive dokonce každá implementace kolekcí může mít ty požadavky trochu jiné. Podstatné je splnění těch požadavků. Lapidárně řečeno, objekt se může měnit, jak chce, ale dokud bude mít stejný hashCode a bude správně odpovídat na equals, je to v pořádku.

Pokud se podívám, jak framework implementuje hashCode, compareTo a equals, neměl bych v kolekcích ani při modifikaci narazit na problém. Je to tak? Resp. se to asi dočtu v té kapitole Publication and escape v Java Concurrency in Practice.
Nejprve si musíte určit, co vlastně znamená, že se jedná o ten samý objekt. Ale pokud vám z toho vyjde, že jeden objekt (konkrétní místo v paměti) může v průběhu své životnosti představovat několik různých objektů (hashCode a equals zahrnují položky, které se mohou změnit), nebude vám to s většinou kolekcí fungovat.

Tohle ale s vícevláknovým přístupem nesouvisí. Vám ten vícevláknový přístup nejspíš rozbil vnitřní implementaci HashMapy použitou v tom LinkedHashSetu. To by modifikovatelné prvky kolekce nezpůsobily, ty by mohly způsobit nanejvýš to, že byste do kolekce nějaký prvek vložil, ale on by tam později nebyl, nebo byste do kolekce vložil prvek, ale později byste tam našel jiný.

3507
Získám tím sdílený stav.
Získáte tím stav sdílený mezi jedním singletonem. To je trošku nesmysl, ne? A je to přesně to, co vás vypeklo – že jste jeden singleton měl z poloviny udělaný jedním způsobem a z poloviny druhým.

3508
K imagesQueue se nikdo jiný než Calendar nedostane, je privátní a nemá getter ani setter. Takže by mělo stačit synchronizovat příslušné metody v Calendar. Chyba byla asi v tom, že jsem pouze přidal klíčové slovo synchronized k těm metodám - s vědomím toho, že Calendar je singleton, což ale asi neplatí, protože tam může být ve skutečnosti více ekvivalentních instancí (v terminologii frameworku se tomu ale říká singleton). Nechal jsem se tím označením zřejmě svést (ale musím to ještě ověřit).
To použití je špatné tak jako tak. Pokud ten objekt má být singleton na zodpovědnost uživatele („není důvod mít víc instancí, ale když vzniknou, nemělo by to ničemu vadit“), má mít ten set jako instanční proměnnou. Pokud to má být tvrdý singleton (nesmí existovat víc kopií), musíte v kódu zajistit, aby to opravdu nemohlo nastat. Navíc takovéhle použití statického fieldu je bad practice, nic tím nezískáte a akorát si zavíráte dveře – nebudete moci ten objekt pořádně testovat, bude špatně spolupracovat s frameworky atd.

3509
Může to být chybná deserializace nebo nějaká manipulace s privátními fieldy té třídy LinkedHashSet, případně nesyncrhonizovnaý přístup z více vláken a nebo se tam dostane null hodnota. HashMap (pomocí které je LinkedHashSet implementován), udržuje počet prvků v mapě jako samostatný field, který se při každé modifikaci mapy přepočítá. Podle mne se rozjede stav toho fieldu se skutečným stavem mapy.

3510
Server / Re:Nefunguje ssl proxy
« kdy: 09. 04. 2018, 22:02:00 »
No to není řešení, problém je v tom, že pokud spustím php aplikaci https://example.com:4431, app se načte ale její odkazy na další stránky již budou https://example.com/other-page-1, https://example.com/other-page-2 atd.. a to už jsem úplně na jiném serveru a s portem 443.
Já ten problém nevidím. Připojíte se na https://example.com (na portu 443). Tam poběží reverzní proxy server, třeba nginx. Ten váš požadavek přepošle třeba na http://example.com:331/. V odpovědi nahradí všechny výskyty http://example.com:331/ nebo třeba http://example.com/ za https://example.com/. Tu odpověď pošle prohlížeči, takže prohlížeč uvidí jen odkazy na https://example.com/. Takže když stránka poslala odkaz na http://example.com/other-page-1, prohlížeč dostane odkaz na https://example.com/other-page-1. Kde je ten problém? Problém by nastal jedině tehdy, pokud by se ten odkaz skládal dynamicky až v JavaScriptu na klientovi, ale to by také šlo nějak ošetřit.

Stran: 1 ... 232 233 [234] 235 236 ... 375