001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.issue; 015 016import java.util.concurrent.locks.Lock; 017import java.util.concurrent.locks.ReentrantLock; 018 019/** 020 * Example code illustrating locking policies in the JDK. 021 * See http://jira.qos.ch/browse/LBCORE-97 for a discussion. 022 * 023 * @author Joern Huxhorn 024 */ 025public class LBCORE97 { 026 027 static int THREAD_COUNT = 10; 028 029 public static void main(String args[]) throws InterruptedException { 030 031 System.out.println("Environment:"); 032 System.out.println("java.runtime.name = " + System.getProperty("java.runtime.name")); 033 System.out.println("java.runtime.version = " + System.getProperty("java.runtime.version")); 034 System.out.println("java.vendor = " + System.getProperty("java.vendor")); 035 System.out.println("java.version = " + System.getProperty("java.version")); 036 System.out.println("java.vm.name = " + System.getProperty("java.vm.name")); 037 System.out.println("java.vm.info = " + System.getProperty("java.vm.info")); 038 039 System.out.println("os.name = " + System.getProperty("os.name")); 040 System.out.println("os.version = " + System.getProperty("os.version")); 041 System.out.println("os.arch = " + System.getProperty("os.arch")); 042 System.out.println("##########################################"); 043 044 usingSynchronized(THREAD_COUNT); 045 usingUnfairLock(THREAD_COUNT); 046 usingFairLock(THREAD_COUNT); 047 } 048 049 public static void execute(String text, Thread[] threads) throws InterruptedException { 050 System.out.println("About to execute " + text + "..."); 051 int threadCount = threads.length; 052 for (int i = 0; i < threadCount; i++) { 053 threads[i].start(); 054 } 055 056 Thread.sleep(10000); 057 058 for (int i = 0; i < threadCount; i++) { 059 threads[i].interrupt(); 060 } 061 Thread.sleep(1000); // wait a moment for termination, to lazy for join ;) 062 } 063 064 public static void print(String text, Runnable[] runnables) { 065 System.out.println("Results for " + text + ":"); 066 for (int i = 0; i < runnables.length; i++) { 067 System.out.println("runnables[" + i + "]: " + runnables[i]); 068 } 069 System.out.println("##########################################"); 070 } 071 072 public static void usingSynchronized(int threadCount) throws InterruptedException { 073 Object lockObject = new Object(); 074 Runnable[] runnables = new Runnable[threadCount]; 075 Thread[] threads = new Thread[threadCount]; 076 077 for (int i = 0; i < threadCount; i++) { 078 runnables[i] = new SynchronizedRunnable(lockObject); 079 threads[i] = new Thread(runnables[i]); 080 } 081 String text = "usingSynchronized"; 082 execute(text, threads); 083 print(text, runnables); 084 } 085 086 public static void usingUnfairLock(int threadCount) throws InterruptedException { 087 Lock lock = new ReentrantLock(); 088 Runnable[] runnables = new Runnable[threadCount]; 089 Thread[] threads = new Thread[threadCount]; 090 091 for (int i = 0; i < threadCount; i++) { 092 runnables[i] = new LockRunnable(lock); 093 threads[i] = new Thread(runnables[i]); 094 } 095 096 String text = "usingUnfairLock"; 097 execute(text, threads); 098 print(text, runnables); 099 } 100 101 public static void usingFairLock(int threadCount) throws InterruptedException { 102 Lock lock = new ReentrantLock(true); 103 Runnable[] runnables = new Runnable[threadCount]; 104 Thread[] threads = new Thread[threadCount]; 105 106 for (int i = 0; i < threadCount; i++) { 107 runnables[i] = new LockRunnable(lock); 108 threads[i] = new Thread(runnables[i]); 109 } 110 111 String text = "usingFairLock"; 112 execute(text, threads); 113 print(text, runnables); 114 } 115 116 public static class SynchronizedRunnable implements Runnable { 117 private final Object lockObject; 118 private int counter; 119 private boolean running; 120 121 public SynchronizedRunnable(Object lockObject) { 122 this.lockObject = lockObject; 123 this.counter = 0; 124 this.running = false; 125 } 126 127 public void run() { 128 running = true; 129 for (;;) { 130 synchronized (lockObject) { 131 counter++; 132 try { 133 Thread.sleep(10); 134 } catch (InterruptedException ex) { 135 break; 136 } 137 } 138 } 139 running = false; 140 } 141 142 public String toString() { 143 return "SynchronizedRunnable[counter=" + counter + ", running=" + running + "]"; 144 } 145 } 146 147 public static class LockRunnable implements Runnable { 148 private final Lock lock; 149 private int counter; 150 private boolean running; 151 152 public LockRunnable(Lock lock) { 153 this.lock = lock; 154 this.counter = 0; 155 this.running = false; 156 } 157 158 public void run() { 159 running = true; 160 for (;;) { 161 lock.lock(); 162 try { 163 counter++; 164 Thread.sleep(10); 165 } catch (InterruptedException ex) { 166 break; 167 } finally { 168 lock.unlock(); 169 } 170 } 171 running = false; 172 } 173 174 public String toString() { 175 return "LockRunnable[counter=" + counter + ", running=" + running + "]"; 176 } 177 } 178}