<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Frostman's blog]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://slukjanov.name/</link><image><url>https://slukjanov.name/favicon.png</url><title>Frostman&apos;s blog</title><link>https://slukjanov.name/</link></image><generator>Ghost 6.32</generator><lastBuildDate>Tue, 21 Apr 2026 07:30:11 GMT</lastBuildDate><atom:link href="https://slukjanov.name/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Ghost welcome post]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;ve decided to keep the ghost welcome post for history.</p>
<hr>
<p>You&apos;re live! Nice. We&apos;ve put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at <code>&lt;</code></p>]]></description><link>https://slukjanov.name/2014/09/11/welcome-to-ghost/</link><guid isPermaLink="false">5a84584412038400188cff49</guid><category><![CDATA[Getting Started]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Thu, 11 Sep 2014 11:46:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;ve decided to keep the ghost welcome post for history.</p>
<hr>
<p>You&apos;re live! Nice. We&apos;ve put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at <code>&lt;your blog URL&gt;/ghost/</code>. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!</p>
<h2 id="gettingstarted">Getting Started</h2>
<p>Ghost uses something called Markdown for writing. Essentially, it&apos;s a shorthand way to manage your post formatting as you write!</p>
<p>Writing in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use <em>shortcuts</em> to <strong>style</strong> your content. For example, a list:</p>
<ul>
<li>Item number one</li>
<li>Item number two
<ul>
<li>A nested item</li>
</ul>
</li>
<li>A final item</li>
</ul>
<p>or with numbers!</p>
<ol>
<li>Remember to buy some milk</li>
<li>Drink the milk</li>
<li>Tweet that I remembered to buy the milk, and drank it</li>
</ol>
<h3 id="links">Links</h3>
<p>Want to link to a source? No problem. If you paste in url, like <a href="http://ghost.org/?ref=slukjanov.name">http://ghost.org</a> - it&apos;ll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here&apos;s a link to <a href="http://ghost.org/?ref=slukjanov.name">the Ghost website</a>. Neat.</p>
<h3 id="whataboutimages">What about Images?</h3>
<p>Images work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:</p>
<p><img src="https://ghost.org/images/ghost.png" alt="The Ghost Logo" loading="lazy"></p>
<p>Not sure which image you want to use yet? That&apos;s ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:</p>
<p>![A bowl of bananas]</p>
<h3 id="quoting">Quoting</h3>
<p>Sometimes a link isn&apos;t enough, you want to quote someone on what they&apos;ve said. It was probably very wisdomous. Is wisdomous a word? Find out in a future release when we introduce spellcheck! For now - it&apos;s definitely a word.</p>
<blockquote>
<p>Wisdomous - it&apos;s definitely a word.</p>
</blockquote>
<h3 id="workingwithcode">Working with Code</h3>
<p>Got a streak of geek? We&apos;ve got you covered there, too. You can write inline <code>&lt;code&gt;</code> blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.</p>
<pre><code>.awesome-thing {
    display: block;
    width: 100%;
}
</code></pre>
<h3 id="readyforabreak">Ready for a Break?</h3>
<p>Throw 3 or more dashes down on any new line and you&apos;ve got yourself a fancy new divider. Aw yeah.</p>
<hr>
<h3 id="advancedusage">Advanced Usage</h3>
<p>There&apos;s one fantastic secret about Markdown. If you want, you can  write plain old HTML and it&apos;ll still work! Very flexible.</p>
<input type="text" placeholder="I&apos;m an input field!">
<p>That should be enough to get you started. Have fun - and let us know what you think :)</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Mountain Lion and iStat Pro]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m using OS X at my MBP as a main operation system and iStat Pro widget<br>
for Dashboard to monitor temps, processes, etc.<br>
After upgrading to OS X 10.8 Mountain Lion the processes section was not working.</p>
<p>Here is a small instruction to make processes be displayed</p>]]></description><link>https://slukjanov.name/2012/08/08/mountain-lion-and-istat-pro/</link><guid isPermaLink="false">5a84584412038400188cff68</guid><category><![CDATA[tips]]></category><category><![CDATA[os x]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Wed, 08 Aug 2012 14:58:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m using OS X at my MBP as a main operation system and iStat Pro widget<br>
for Dashboard to monitor temps, processes, etc.<br>
After upgrading to OS X 10.8 Mountain Lion the processes section was not working.</p>
<p>Here is a small instruction to make processes be displayed again.</p>
<ol>
<li>
<p>Open iStat Pro widget directory, it is located in <code>~/Library/Widgets/iStat\ Pro.wdgt/</code><br>
or <code>/Library/Widgets/iStat\ Pro.wdgt/</code> (in Finder you should use <code>Show Package Contents</code> in context menu<br>
of the specified folder to open the widget&apos;s contents);</p>
</li>
<li>
<p>If you are using horizontal (wide) widget edit the <code>Wide.js</code> file and if<br>
vertical (tall) - <code>Tall.js</code>;</p>
</li>
<li>
<p>Find function <code>WideSkinController.prototype.updateProcesses = function(){</code> and<br>
replace all <code>PID|$1</code> with <code>PID| $1</code> (add space after pipe) in this section. So, you should<br>
get something like this:</p>
</li>
</ol>
<pre><code class="language-language-javascript">WideSkinController.prototype.updateProcesses = function(){
	var _self = this;
	var exclude = &quot;&quot;;
	if(p.v(&quot;processes_excludewidgets&quot;) == &apos;on&apos;)
		exclude = &quot; grep -v DashboardClient | &quot;;
	
	if(p.v(&quot;processes_sort_mode&quot;) == &apos;cpu&apos;)
		widget.system(&apos;ps -arcwwwxo &quot;pid %cpu command&quot; | egrep &quot;PID| $1&quot; | grep -v grep | &apos; + exclude + &apos; head -7 | tail -6 | awk \&apos;{print &quot;&lt;pid&gt;&quot;$1&quot;&lt;/pid&gt;&lt;cpu&gt;&quot;$2&quot;&lt;/cpu&gt;&lt;name&gt;&quot;$3,$4,$5&quot;&lt;/name&gt;&lt;/item&gt;&quot;}\&apos;&apos;, function(data){ _self.updateProcessesOut(data);});
	else
		widget.system(&apos;ps -amcwwwxo &quot;pid rss command&quot;  | egrep &quot;PID| $1&quot; | grep -v grep | &apos; + exclude + &apos; head -7 | tail -6 | awk \&apos;{print &quot;&lt;pid&gt;&quot;$1&quot;&lt;/pid&gt;&lt;cpu&gt;&quot;$2&quot;&lt;/cpu&gt;&lt;name&gt;&quot;$3,$4,$5&quot;&lt;/name&gt;&lt;/item&gt;&quot;}\&apos;&apos;, function(data){ _self.updateProcessesOut(data);});
}
</code></pre>
<ol start="4">
<li>Restart the iStat Pro widget and the processes list will be working again!</li>
</ol>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[SSH Tunneling]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I create SSH tunnels every day and this article is a small introduction into the SSH tunneling<br>
(also known as &quot;port forwarding&quot;).<br>
A secure shell (SSH) tunnel consists of an encrypted tunnel created through a SSH protocol connection.<br>
Users may set up SSH tunnels to transfer unencrypted traffic</p>]]></description><link>https://slukjanov.name/2012/03/28/ssh-tunneling/</link><guid isPermaLink="false">5a84584412038400188cff62</guid><category><![CDATA[ssh]]></category><category><![CDATA[port forwarding]]></category><category><![CDATA[tunneling]]></category><category><![CDATA[tips]]></category><category><![CDATA[*nix]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Wed, 28 Mar 2012 04:01:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I create SSH tunnels every day and this article is a small introduction into the SSH tunneling<br>
(also known as &quot;port forwarding&quot;).<br>
A secure shell (SSH) tunnel consists of an encrypted tunnel created through a SSH protocol connection.<br>
Users may set up SSH tunnels to transfer unencrypted traffic over a network through an encrypted channel.<br>
SSH is typically used to log into a remote machine and execute commands, but it also supports tunneling,<br>
forwarding TCP ports and X11 connections; it can transfer files using the associated SSH file transfer (SFTP)<br>
or secure copy (SCP) protocols. Also tunnels provide an ability to bypass firewalls :)</p>
<p>So, let&apos;s start. Ports can be forwarded in three ways:</p>
<ol>
<li>Local port forwarding;</li>
<li>Remote port forwarding;</li>
<li>Dynamic port forwarding (proxy).</li>
</ol>
<p>Wikipedia says that:</p>
<blockquote>
<p>Port forwarding or port mapping is a name given to the combined technique of</p>
<ul>
<li>translating the address and/or port number of a packet to a new destination</li>
<li>possibly accepting such packet(s) in a packet filter (firewall)</li>
<li>forwarding the packet according to the routing table.</li>
</ul>
</blockquote>
<h2 id="tunnelingwithlocalportforwarding">Tunneling with local port forwarding</h2>
<p>Let&apos;s imagine that there are some computers with specific abilities:</p>
<ul>
<li><code>work</code> - can&apos;t access <code>target</code> (for example, <code>target</code> is blocked by firewall or <code>target</code> can be<br>
unaccessible from the <code>work</code>&apos;s network)</li>
<li><code>bridge</code> (<code>gateway</code>) - accessible from <code>work</code> and can access <code>target</code> (need to have IP accessible from <code>work</code>)</li>
</ul>
<p>So, we want to access <code>target</code> throw the <code>global</code> machine.</p>
<p><code>Access from work computer to some external banned resource</code></p>
<p>To create the SSH tunnel you should execute the following command from <code>work</code> (<code>local</code>) machine:</p>
<pre><code class="language-language-bash">ssh -L [&lt;local-address-to-listen&gt;:]&lt;local-port-to-listen&gt;:&lt;target-host&gt;:&lt;target-port&gt; &lt;bridge&gt;
</code></pre>
<p>Now the SSH client at <code>work</code> will connect to the SSHd running at <code>bridge</code> and bind <code>&lt;target-host&gt;:&lt;target-port&gt;</code><br>
to listen for local requests to <code>[&lt;local-address-to-listen&gt;:]&lt;local-port-to-listen&gt;</code>. At the <code>bridge</code><br>
end the connection to <code>&lt;target-host&gt;:&lt;target-port&gt;</code> will be created. So <code>work</code> doesn&#x2019;t need to know how to connect to<br>
<code>&lt;target-host&gt;:&lt;target-port&gt;</code>, only <code>bridge</code> needs to worry about that. The channel between <code>work</code> and <code>bridge</code> will be<br>
<strong>encrypted</strong> (SSH tunnel), but the connection between <code>bridge</code> and <code>&lt;target-host&gt;:&lt;target-port&gt;</code> will be <strong>unencrypted</strong>.</p>
<p>After executing this command, it is possible to access <code>&lt;target-host&gt;:&lt;target-port&gt;</code> by accessing<br>
<code>[&lt;local-address-to-listen&gt;:]&lt;local-port-to-listen&gt;</code> at <code>work</code> computer. The <code>bridge</code> computer will act as a gateway<br>
which would accept requests from <code>work</code> machine and fetch data/tunnelling it back.</p>
<h2 id="tunnelingwithremoteportforwardingreversedtunneling">Tunneling with remote port forwarding  (reversed tunneling)</h2>
<p>Let&apos;s reverse the problem.</p>
<ul>
<li><code>home</code> - can&apos;t access <code>target</code> (for example, <code>target</code> is protected by firewall or <code>target</code> can be unacessible from the<br>
<code>home</code>&apos;s network)</li>
<li><code>bridge</code> (<code>gateway</code> or <code>work</code>) - accessible from <code>home</code> and can access <code>target</code> (need to have IP accessible from <code>home</code>)</li>
</ul>
<p>To create the SSH tunnel you should execute the following command from <code>bridge</code> (<code>gateway</code>/<code>work</code>) machine:</p>
<pre><code class="language-language-bash">ssh -R [&lt;home-address-to-listen&gt;:]&lt;home-port-to-listen&gt;:&lt;target-host&gt;:&lt;target-port&gt; &lt;home&gt;
</code></pre>
<p>After executing of this command, the SSH client at <code>bridge</code> will connect to SSHd running at <code>home</code> and create the tunnel.<br>
Then the server will bind <code>[&lt;home-address-to-listen&gt;:]&lt;home-port-to-listen&gt;</code> to listen for incoming requests which would<br>
be routed through the created SSH tunnel between <code>home</code> and <code>gateway</code>. Now it&#x2019;s possible to access the &quot;internal&quot;<br>
resource <code>&lt;target-host&gt;:&lt;target-port&gt;</code> by accessing <code>[&lt;home-address-to-listen&gt;:]&lt;home-port-to-listen&gt;</code> from the <code>home</code><br>
machine. The <code>gateway</code> will then create a connection to <code>&lt;target-host&gt;:&lt;target-port&gt;</code> and relay back the response to<br>
<code>home</code> via the created SSH tunnel.</p>
<p>With this approach we need to create the splitted SSH tunnel for each new resource. But SSH provides us an ability to<br>
proxy traffic to any resource using SSH tunnel and it named <code>dynamic port forwarding</code>.</p>
<h2 id="dynamicportforwardingproxy">Dynamic port forwarding (proxy)</h2>
<p>Dynamic port forwarding provides us an ability to configure one local port for tunnelling data to all remote destinations<br>
using the SOCKS protocol. At the client side of the SSH tunnel a SOCKS proxy would be created and any application that can<br>
work throw SOCKS protocol can use it to access some resources that accessible only from the other host.</p>
<pre><code class="language-language-bash">ssh -D [&lt;local-address-to-listen&gt;:]&lt;local-port-to-listen&gt; &lt;gateway&gt;
</code></pre>
<h2 id="additionalsshflags">Additional SSH flags</h2>
<p>There are several intresting <code>ssh</code> command flags:</p>
<ul>
<li><code>-v</code> - verbose output</li>
<li><code>-q</code> - quiet mode</li>
<li><code>-1</code> - forces ssh to try protocol version 1 only</li>
<li><code>-2</code> - forces ssh to try protocol version 2 only</li>
<li><code>-4</code> - forces ssh to use IPv4 addresses only</li>
<li><code>-6</code> - forces ssh to use IPv6 addresses only</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Shell improvements with Zsh]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>First of all, I want to say that the most part of materials for this article I found in the internet.<br>
This is an agregation of usefull tips for zsh.</p>
<p>Here is my <em>.zshrc</em> file: <a href="https://gist.github.com/Frostman/1754521?ref=slukjanov.name#file-zshrc">https://gist.github.com/Frostman/1754521#file-zshrc</a></p>
<p>There are a lot of terminal&apos;s</p>]]></description><link>https://slukjanov.name/2012/02/06/shell-improvements-with-zsh/</link><guid isPermaLink="false">5a84584412038400188cff5d</guid><category><![CDATA[*nix]]></category><category><![CDATA[zsh]]></category><category><![CDATA[tips]]></category><category><![CDATA[shell]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Mon, 06 Feb 2012 20:20:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>First of all, I want to say that the most part of materials for this article I found in the internet.<br>
This is an agregation of usefull tips for zsh.</p>
<p>Here is my <em>.zshrc</em> file: <a href="https://gist.github.com/Frostman/1754521?ref=slukjanov.name#file-zshrc">https://gist.github.com/Frostman/1754521#file-zshrc</a></p>
<p>There are a lot of terminal&apos;s improvements, such as extended autocompletion and forced rehash.<br>
I use this configuration at Ubuntu 11.10 and Mac OS X 10.7.3.<br>
You can activate autocompletion by <em>Tab</em> button and control it by arrow keys.<br>
It works with files, directories and hosts.</p>
<p>I don&apos;t have much experience in configuring zsh, but feel free to ask me about something you are intersting in.</p>
<p>P.S. Some screen shots of my terminal:</p>
<p><img src="https://storage.ghost.io/c/93/c8/93c8b875-afa0-4d30-9f94-687cf7de7739/content/images/2014/Sep/screen_shot_1.png" alt loading="lazy"><br>
<img src="https://storage.ghost.io/c/93/c8/93c8b875-afa0-4d30-9f94-687cf7de7739/content/images/2014/Sep/screen_shot_2.png" alt loading="lazy"><br>
<img src="https://storage.ghost.io/c/93/c8/93c8b875-afa0-4d30-9f94-687cf7de7739/content/images/2014/Sep/screen_shot_3.png" alt loading="lazy"><br>
<img src="https://storage.ghost.io/c/93/c8/93c8b875-afa0-4d30-9f94-687cf7de7739/content/images/2014/Sep/screen_shot_4.png" alt loading="lazy"></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[HTML5 Slides]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Few days ago I encountered a problem with making presentation for techtalk. I didn&apos;t want to use Microsoft PowerPoint<br>
or presentations in Google Docs, because I want to publish slides in my blog. So, it had to be an html5<br>
application and also it had to be ready</p>]]></description><link>https://slukjanov.name/2011/09/29/html5-slides/</link><guid isPermaLink="false">5a84584412038400188cff51</guid><category><![CDATA[html5]]></category><category><![CDATA[presentations]]></category><category><![CDATA[slides]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Thu, 29 Sep 2011 08:19:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Few days ago I encountered a problem with making presentation for techtalk. I didn&apos;t want to use Microsoft PowerPoint<br>
or presentations in Google Docs, because I want to publish slides in my blog. So, it had to be an html5<br>
application and also it had to be ready to be used in browser with projector.</p>
<p>I found some interesting tool to do it. Enjoy it: <a href="https://github.com/n1k0/landslide?ref=slukjanov.name">LandSlide</a>.</p>
<p>The sample presentation with features overview you can find <a href="http://adamzap.com/random/landslide.html?ref=slukjanov.name#slide1">here</a>.<br>
Use <strong>&#x2190;</strong> and <strong>&#x2192;</strong> to browse slides.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Lock and ReentrantLock]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This article is about locks in Java. Here you can read about their usage, fairness policies and performance.</p>
<p>Locks are available since <strong>Java 1.5</strong>.</p>
<h2 id="interfaces">Interfaces</h2>
<p>First of all, lets see at interfaces.</p>
<p><a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html?ref=slukjanov.name">java.util.concurrent.Lock</a></p>
<pre><code class="language-language-java">public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(</code></pre>]]></description><link>https://slukjanov.name/2011/09/29/lock-and-reentrantlock/</link><guid isPermaLink="false">5a84584412038400188cff56</guid><category><![CDATA[java]]></category><category><![CDATA[concurrency]]></category><category><![CDATA[reentrantlock]]></category><category><![CDATA[lock]]></category><category><![CDATA[readwritelock]]></category><category><![CDATA[reentrantreadwritelock]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Thu, 29 Sep 2011 04:22:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>This article is about locks in Java. Here you can read about their usage, fairness policies and performance.</p>
<p>Locks are available since <strong>Java 1.5</strong>.</p>
<h2 id="interfaces">Interfaces</h2>
<p>First of all, lets see at interfaces.</p>
<p><a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html?ref=slukjanov.name">java.util.concurrent.Lock</a></p>
<pre><code class="language-language-java">public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
</code></pre>
<p>As we see, it prodives opportunity of acquiring lock by different ways:</p>
<ul>
<li>if we are using <code>lock()</code> and the lock is not available the current thread will be suspended until the lock will be released;</li>
<li><code>lockInterruptible()</code> method acquires the lock until the current thread will be interrupted or lock will be released;</li>
<li><code>tryLock()</code> method acquires the lock only if it is available at the time of invocation (non-blocking, not waiting for<br>
the lock will be released);</li>
<li>if we want to acquire the lock interruptibly with the specified waiting timeout we should use <code>tryLock(...)</code> method.</li>
</ul>
<p>There is only one method for unlocking the lock: <code>unlock()</code> and it works as it named.</p>
<p>Locks are more flexible and configurable alternative for <code>synchronized</code> methods and statements, but we should remeber that<br>
instead of synchronized, <strong>noone</strong> will unlock the lock for us if an exception occures or return statement invokes. So,<br>
in most cases, the following idiom should be used:</p>
<pre><code class="language-language-java">Lock l = ...;
l.lock();
try {
    // some business logic that needs to be synchronized
} finally {
    l.unlock();
}
</code></pre>
<p><a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReadWriteLock.html?ref=slukjanov.name">java.util.concurrent.locks.ReadWriteLock</a></p>
<pre><code class="language-language-java">public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}
</code></pre>
<p>ReadWriteLock is a pair of assotiated locks. First lock is used <strong>only</strong> for <strong>read-only</strong> operations (supports <strong>multiple</strong><br>
locks at the same time) and the second lock is for <strong>write</strong> operations (<strong>exclusive</strong> lock). The read lock can be acquired<br>
only if the write lock is released. When we lock the write lock, it will wait for releasing of all read locks and then acquires.<br>
ReadWriteLock will improve performance in case of using multiple readers and much smaller number of writers, because many of<br>
readers will work at the same time.</p>
<h2 id="implementations">Implementations</h2>
<p>Java provides two implementations of these locks that we care about - <code>ReentrantLock</code> and <code>ReentrantReadWriteLock</code>.<br>
As you see, both of them are reentrant. It means that a thread can acquire the same lock multiple times without any<br>
issue. In fact reentrant locking increments special thread-personal counter (unlocking - decrements) and the lock will<br>
be released only when counter reaches zero.</p>
<p>Each of lock&apos;s implementations has additional methods that help us. Here are some of them:</p>
<ul>
<li>for <code>ReentrantLock</code> class:
<ul>
<li><code>isHeldByCurrentThread()</code> returns true iff the lock is locked by the current thread;</li>
<li><code>getHoldCount()</code> returns number (int) of locks on the lock by the current thread;</li>
<li><code>getQueueLength()</code> returns an <strong>estimate</strong> number of threads that waits to acquire the lock;</li>
<li><code>isLocked()</code> returns true if any thread holds this lock and false otherwise;</li>
</ul>
</li>
<li>for <code>ReentrantReadWriteLock</code> class:
<ul>
<li><code>isWriteLocked()</code> returns true if someone holds the write lock;</li>
<li><code>isWriteLockedByCurrentThread()</code> returns true if the lock is locked by the current thread;</li>
<li><code>getReadHoldCount()</code> returns number (int) of locks on the read lock by the current thread.</li>
</ul>
</li>
</ul>
<h2 id="fairness">Fairness</h2>
<p>One of the interesting features of reentrant locks is <strong>fairness</strong>. When we are creating an instance of ReentrantLock or<br>
ReentrantReadWriteLock we can pass fair flag to the constructor. The difference of fair and non-fair locks is in granting<br>
access policy to threads that wait in the queue to lock the lock. The fair lock grants access to the longest-waiting thread,<br>
so it look like FIFO (First-In-First-Out). A non-fair lock does not guarantee any particular access order.<br>
Performance of fair locks is near to <code>synchronized</code> block and non-fair locks is much faster than them.</p>
<p>By default, all locks are non-fair. Synchronized keyword and statement are non-fair, too. Fair locks have some disadvantages:</p>
<ul>
<li>performance degradation;</li>
<li>fair locks do <strong>not guarantiee</strong> fair thread ordering in real world.</li>
</ul>
<p>Micro-benchmarking in Java is not so good as we want. There are several things that can change results of tests:</p>
<ul>
<li>JVM warmup (the code becomes faster and faster while its working);</li>
<li>Class loading (all application classes must be loaded);</li>
<li>JIT compilation (JVM needs time to find hot parts of the code);</li>
<li>GC (gc can happen while benchmarking and increase the time much).</li>
</ul>
<p>Instead of this, I think that we can do some micro-benchmarks to check fair locks performance.<br>
We have T threads, each of them will lock the lock, increment global counter, increment personal counter and unlock the lock.<br>
Test will be ended when the global counter reaches N. So, all threads should have equal values of personal counters<br>
(small deviation can be ignored) with fair lock and different values with non-fair lock. Lets see at average results of running<br>
such micro-benchmark. I ran them for 50 times with <code>N=1000000</code> and <code>T=10</code> on my laptop (<code>i3 330m 2.13GHz</code>, <code>8Gb RAM</code>, <code>JDK 1.7.0</code>)<br>
and aggregated results. &apos;Deviation&apos; - this is how personal counter differs from the expected value (<code>N/T</code>).</p>
<p>Fair Lock</p>
<pre><code>Deviation:
	max: 0,3222%
	avg: 0,0644%
	min: 0,0351%

Average takes: 10304ms
</code></pre>
<p>Non-fair Lock</p>
<pre><code>Deviation:
	max: 20,1312%
	avg: 2,1682%
	min: 0,6022%

Average takes: 104ms
</code></pre>
<p>You can find sources of the test <a href="https://gist.github.com/1250500?ref=slukjanov.name">here</a>.<br>
The results of test match javadoc&apos;s warning about fair locks absolutly:</p>
<pre><code>* Programs using fair locks accessed by many threads
* may display lower overall throughput (i.e., are slower; often much
* slower) than those using the default setting, but have smaller
* variances in times to obtain locks and guarantee lack of
* starvation.
</code></pre>
<p>As we see &quot;much slower&quot; is up to <strong>100</strong> times slower!</p>
<p>So, we should remember about all features of locks and their configurations.<br>
I think that we can use ReentrantLock and ReentrantReadWriteLock without any indeterminacy now.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Synchronized in Java]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>We need synchronizations, when we are writing applications that work with variables from more than one thread. The most simple<br>
way to avoid issues of parallel accessing to variable is to use synchronized statement. In Java there are two ways to use<br>
<code>synchronized</code>:</p>
<ul>
<li>use statement synchronized with some monitor-object to</li></ul>]]></description><link>https://slukjanov.name/2011/09/28/synchronized-in-java/</link><guid isPermaLink="false">5a84584412038400188cff4b</guid><category><![CDATA[java]]></category><category><![CDATA[concurrency]]></category><category><![CDATA[synchronized]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Wed, 28 Sep 2011 16:01:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>We need synchronizations, when we are writing applications that work with variables from more than one thread. The most simple<br>
way to avoid issues of parallel accessing to variable is to use synchronized statement. In Java there are two ways to use<br>
<code>synchronized</code>:</p>
<ul>
<li>use statement synchronized with some monitor-object to create critical section (this is also called &quot;synchronized block&quot;):</li>
</ul>
<pre><code class="language-language-java">synchronized(monitorObject) {
  // Critical section :: 
  // this code block can be accessed 
  // by only one thread at the time
}
</code></pre>
<ul>
<li>mark method with <code>synchronized</code> keyword and then:
<ul>
<li>if method is static, it is equal to <code>synchronized(DeclaredClass.class) { method body }</code>;</li>
<li>if method is not static, it is equal to <code>synchronized(this) { method body }</code>.</li>
</ul>
</li>
</ul>
<p>So, <code>synchronized</code> takes care about preventing locks in case of multiple read/write access to variables from more than one thread<br>
In the latest JVM (since 1.5) <code>synchronized</code> overhead is very low in case of unused synchronizations (when only one thread<br>
try to enter into the synchronized section at a time), but in the old JVMs <code>synchronized</code> was not optimized.</p>
<p><code>synchronized</code> keyword is not so flexible and configurable as we want sometimes, so you can read about Lock and ReadWriteLock in Java<br>
<a href="https://slukjanov.name/blog/2011/09/29/lock-and-reentrantlock/">here</a> (my next article).</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[First post]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Welcome!</p>
<p>It is the first post in my personal blog. I have planned to write some articles about programming and technologies in it. I think that most of them will be written in english.</p>
<p>This blog was based on <a href="http://octopress.org/?ref=slukjanov.name">Octopress</a> blogging framework and was hosted at Github pages in time</p>]]></description><link>https://slukjanov.name/2011/09/27/first-post/</link><guid isPermaLink="false">5a84584412038400188cff4f</guid><category><![CDATA[welcome]]></category><dc:creator><![CDATA[Sergey Lukjanov]]></dc:creator><pubDate>Tue, 27 Sep 2011 13:48:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Welcome!</p>
<p>It is the first post in my personal blog. I have planned to write some articles about programming and technologies in it. I think that most of them will be written in english.</p>
<p>This blog was based on <a href="http://octopress.org/?ref=slukjanov.name">Octopress</a> blogging framework and was hosted at Github pages in time when I was initially writing this post. You could find a new post about moving my blog to ghost.</p>
<p>You can subscribe to this blog via <a href="http://feeds.feedburner.com/slukjanov?ref=slukjanov.name">rss</a> or <a href="http://feedburner.google.com/fb/a/mailverify?uri=slukjanov&amp;ref=slukjanov.name">email</a>.</p>
<p>You could take a look at <a href="http://oldblog.slukjanov.name/?ref=slukjanov.name">the old copy of my blog</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>