Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JKeyLockManager

JKeyLockManager (KLM) provides fine-grained locking with application specific keys. All resource and exception handling for the active set of keys is encapsulated in the manager. Thereby it is easier to follow the recommendation of Robert C. Martin: "Keep your concurrency-related code separate from other code."

Abstract

The KLM offers the possibility of performing callbacks within a lock. It selects the lock on the basis of a given key.

manager.executeLocked("test1", () -> { // run block in lock });

The KLM takes over the maintenance of the locks and keys completely. It can manage arbitrary quantities of keys and locks. One lock is assigned to each key and the necessary locks are produced automatically. The KLM ensures that unneeded keys and locks are being released quickly.

Behavior with concurrency

If a thread executes a callback with a key A, a second thread can execute a callback with a key B concurrently. Another thread, which is trying to execute a callback with a key A, has to wait until the first thread leaves the callback.

The methods of the KLM are reentrant and interruptible.

Example - web service with concurrency constraint

A local system exports weather data to a distributed web service. The service is called for a large set of cities and every service access for a city has a high response time. Since the service is made available on a cluster, the import can be strongly accelerated by concurrent access. The service forbids concurrent access to the weather data of the same city. A simple lock is used in order to ensure compliance with this constraint.

A simple solution with a global lock

publicclassWeatherServiceProxy {
publicsynchronizedvoidupdateWeatherData(StringcityName, floattemperature) {
delegate.updateWeatherData(cityName, temperature); }
}

Solution with KLM

publicclassWeatherServiceProxy {
privatefinalKeyLockManagerlockManager = KeyLockManagers.newManager();
publicvoidupdateWeatherData(StringcityName, floattemperature) {
lockManager.executeLocked(cityName, () -> delegate.updateWeatherData(cityName, temperature)); }

Now threads that work on weather data from different cities can enter the locked section concurrently. Compliance with the constraint and speedup has been achieved.

Getting started

Maven

Java 8

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>2.1.0</version>
</dependency>

Java 5, 6, 7

<dependency>
<groupId>de.jkeylockmanager</groupId>
<artifactId>jkeylockmanager</artifactId>
<version>1.2.0</version>
</dependency>

Source

Start with KeyLockManagers in order to get instances of KLM.

Versions

Version 2

2.1.0

Make number of stripes configurable (Based on pull request from https://github.com/jschmied)

Example
KeyLockManagerlockManager = newStripedKeyLockManager(10, TimeUnit.MINUTES, 120);
2.0.0

Use of Java 8

Version 1

Version 1.2.0

Backport from Version 2 - Make number of stripes configurable

Version 1.1.0

Simplified exception handling.

Execution exceptions inside of callbacks are no longer wrapped. Callbacks now have to wrap checked exceptions in unchecked exceptions.

Version 1.0.1

Transition to maven central

Build state

master

Build Status

version-1

Build Status

About

JKeyLockManager provides fine-grained locking with application specific keys.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages