'3. Implementation/Java'에 해당되는 글 12건
- 2016.07.21 Functions as First-Class Values (1등 시민으로서의 함수)
- 2015.02.02 cglib - Byte Code Generation Library
- 2015.01.13 Set up spring MVC development environment using Luna
- 2014.11.29 Stop thread using own flag and interrupt method
- 2013.09.10 Jenkins Plugin Development 참고 사이트
- 2011.11.24 Java Reflection 관련
- 2011.07.21 간단한 클래스 이름 가져오기
- 2010.08.14 인스턴스 초기화
- 2010.08.14 JNI - Java Native Interface
- 2010.08.14 inner class and static nested class
- 2009.08.26 jar 파일 실행 법
- 2009.07.28 wait & notify & notifyAll
Functions as First-Class Values (1등 시민으로서의 함수)

What is Functions as First-Class Values?
This is translated as "1등 시민으로서의 함수" in Korean. (Why is this translated like that?)
First class? 1등 시민?
First-class (en-en dictionary)
: If you describe something or someone as first-class, you mean that they are extremely good and of the highest quality.
A class of this term does not mean the class of java. It seems that to distinguish class word from general java class "시민" might be used.
But it causes me to understand it more confused.
Anyway, return to the subject.
In Java, we are accustomed to passing objects and primitive values to methods, returning them from methods, and assigning them to variables. This means that objects and primitives are first-class values in Java.
Java cannot declare any function without a class. Instead java only has methods.
But methods aren't first-class in Java.
You can't pass a method as an argument to another methods, return a method from a method, or assign a method as a value to a variable.
However, most anonymous inner classes are effectively function "wrappers".
Many Java methods take an instance of an interface that declares one method.
package functions; import java.awt.*; import java.awt.event.*; class HelloButtonApp2 { private final Button button = new Button(); public HelloButtonApp2() { button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Hello There: event received: " + e); } }); } }
Let's introduce a abstraction for all these "function objects"!.
package functions; public interface Function1Void( <A >) { void apply(A a); }
And let's try to use Function1Void like :
package functions; import java.fawt.*; import java.fawt.event.*; class FunctionalHelloButtonApp { private final Button button = new Button(); public FunctionalHelloButtonApp() { button.addActionListener(new Function1Void <ActionEvent >() { // 1 public void apply(ActionEvent e) { // 2 System.out.println("Hello There: event received: "+e); } }); } }
Abstraction callback function is great but instead of using this, lambda approach on Java 8 is better.
Refer : Functional Programming for Java Developers by Dean Wampler
https://github.com/cglib/cglib/wiki
Here is good example for this:
http://markbramnik.blogspot.kr/2010/04/cglib-introduction.html
In addition, I attached sample project to be able to run his explanation:
TODO: I need to investigate and study cglib's usage more!
It's now widely used at famous frameworks like Hibernate, Spring and more.
Set up spring MVC development environment using Luna

This guide sets up Spring MVC development environment with maven
1. Download eclipse luna
2. Install STS (Spring Tool Suite)
- Run eclipse
- Find the Help > Eclipse Marketplace menu on toolbar
- Type 'sts' on Search tab
- Click 'install' button which title is 'Spring Tool Suite (STS) for Eclipse Luna ~~~~
- Restart eclipse
- Find the Help > Eclipse Marketplace menu on toolbar
- Type 'm2e' on Search tab
- Click 'install' button which title is 'Maven Integration for Eclipse (Luna) 1.5.0'
- If this was already installed, the buttons are Update and Uninstall. If so, skip this step.
- Restart eclipse
- File > New > Project
- Type the spring then select 'Spring Project'
- Select the 'Spring MVC Project' template and specify a project name
- Proceed nexts until you met the dialog that asks package name
- Enter any package name and finish it.
Stop thread using own flag and interrupt method

Here is the sample code that explains how to stop thread using own flag and interrupt method respectively.
public class Main { static interface IClosableThread { void start(); void close(); } static class StopThreadUsingFlag extends Thread implements IClosableThread { private boolean stopThis = false; public void run() { try { while (this.stopThis == false) { System.out.print("."); Thread.sleep(500); } } catch (InterruptedException e) { } System.out.println(); System.out.println("Finished!"); } public void close() { this.stopThis = true; try { this.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } static class StopThreadUsingInterrupt extends Thread implements IClosableThread { public void run() { try { while (!this.isInterrupted()) { System.out.print("."); Thread.sleep(500); } } catch (InterruptedException e) { } System.out.println(); System.out.println("Finished!"); } public void close() { this.interrupt(); try { this.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { System.out.println("Hello, Java!"); IClosableThread thread = new Main.StopThreadUsingFlag(); thread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } thread.close(); thread = new Main.StopThreadUsingInterrupt(); thread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } thread.close(); } }
- http://hudson-ci.org/docs/index.html
- https://wiki.jenkins-ci.org/display/JENKINS/Extend+Jenkins
- https://wiki.jenkins-ci.org/display/JENKINS/Plugins
- https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial
- http://wiki.hudson-ci.org/display/HUDSON/Extend+Hudson
- http://jenkins-ci.org/category/sections/development
import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflectionTest { public static class Base{ protected int mFlag = 2; protected void print() { System.out.println("Base.Print"); } } public static class Derived extends Base { public Derived() { mFlag = 3; } @Override protected void print() { System.out.println("Dervied.Print"); } } public static void printWithReflection(Base base) { try { Field field = Base.class.getDeclaredField("mFlag"); field.setAccessible(true); int flag = field.getInt(base); System.out.println(flag); Method method = Base.class.getDeclaredMethod("print", null); method.setAccessible(true); method.invoke(base, null); } catch (Exception e) { } } public static void main(String [] args) { Base base = new Base(); Derived derived = new Derived(); printWithReflection(base); printWithReflection(derived); } }
위 코드에서 Derived 라는 클래스는 Base 클래스의 print 함수를 overriding 하였고, printWithReflection 함수는 Derived 클래스가 아닌 Base 클래스를 이용하여 Field 와 Method 를 받아서 호출하였습니다. 결과는 아래와 같이 overriding 하더라도 문제없이 동작하였습니다.
2 Base.Print 3 Dervied.Print |
간단하지만 모르면 . 을 파싱해서 원하는 클래스 이름을 반환하는 함수를 작성하여 사용했었습니다. 물론 아무 의심 없이 구글링을 해서 얻은 정보였습니다. 나쁘진 않지만 간단한 함수가 이미 제공되고 있습니다. 바로 Class 의 getSimpleName() 입니다.
TestClass testClass = new TestClass(); testClass.class.getSimpleName();
Class 클래스의 자세한 정보는 아래 링크 참고:
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Class.html
public class Foo { public Foo() { System.out.println("constructor called"); } static { System.out.println("static initializer called"); } { System.out.println("instance initializer called"); } }
new Foo(); new Foo();
static initializer called instance initializer called constructor called instance initializer called constructor called
import java.util.*; class ReadFile { //Native method declaration native byte[] loadFile(String name); //Load the library static { System.loadLibrary("nativelib"); } public static void main(String args[]) { byte buf[]; //Create class instance ReadFile mappedFile=new ReadFile(); //Call native method to load ReadFile.java buf=mappedFile.loadFile("ReadFile.java"); //Print contents of ReadFile.java for(int i=0;i<buf.length;i++) { System.out.print((char)buf[i]); } } }
native byte[] loadFile(String name);
static { System.loadLibrary("nativelib"); }
/* * Class: ReadFile * Method: loadFile * Signature: (Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile (JNIEnv *, jobject, jstring);
#include <jni.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile (JNIEnv * env, jobject jobj, jstring name) { caddr_t m; jbyteArray jb; jboolean iscopy; struct stat finfo; const char *mfile = (*env)->GetStringUTFChars( env, name, &iscopy); int fd = open(mfile, O_RDONLY); if (fd == -1) { printf("Could not open %s\n", mfile); } lstat(mfile, &finfo); m = mmap((caddr_t) 0, finfo.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (m == (caddr_t)-1) { printf("Could not mmap %s\n", mfile); return(0); } jb=(*env)->NewByteArray(env, finfo.st_size); (*env)->SetByteArrayRegion(env, jb, 0, finfo.st_size, (jbyte *)m); close(fd); (*env)->ReleaseStringUTFChars(env, name, mfile); return (jb); }
Gnu C/Linux: gcc -o libnativelib.so -shared -Wl,-soname,libnative.so -I/export/home/jdk1.2/include -I/export/home/jdk1.2/include/linux nativelib.c -static -lc Gnu C++/Linux with Xbase g++ -o libdbmaplib.so -shared -Wl,-soname,libdbmap.so -I/export/home/jdk1.2/include -I/export/home/jdk1.2/include/linux dbmaplib.cc -static -lc -lxbase Win32/WinNT/Win2000 cl -Ic:/jdk1.2/include -Ic:/jdk1.2/include/win32 -LD nativelib.c -Felibnative.dll
Unix or Linux: LD_LIBRARY_PATH=`pwd` export LD_LIBRARY_PATH Windows NT/2000/95: set PATH=%path%;.
OuterClass.StaticNestedClass |
예를 들어, 정적 중첩 클래스의 객체를 생성하기 위해서는 아래 구문을 사용합니다.
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass(); |
class OuterClass { ... class InnerClass { ... } } |
내부 클래스의 인스턴스는 외부 클래스 (outer class)의 인스턴스 내에서만 존재할 수 있으며 메소드 및 필드 역시 '외부클래스.내부클래스' 형식으로 접근할 수 있습니다.
OuterClass.InnerClass innerObject = outerObject.new InnerClass(); |
java -jar filename.jar
|
출처 : 구글링, http://ubuntuforums.org/showthread.php?t=348698


쓰레드는 wait 메소드를 실행하면 동작을 일시 정지하고 wait 셋이라고 하는 대합실로 들어간다. 쓰레드는 다음중 어느 한 상황이 발생하기 전까지는 영원히 그 wait 셋 안에서 잠들어 있게 된다.
- 다른 쓰레드에서 notify 메소드에 의해 깨어난다.
- 다른 쓰레드에서 notifyAll 메소드에 의해 깨어난다.
- 다른 쓰레드에서 interrupt 메소드에 의해 깨어난다.
- wait 메소드가 타임아웃 된다.
wait 메소드를 실행하기 위해서는 쓰레드가 락을 가지고 있어야 한다. 그러나 wait 셋에 들어갈 때 쓰레드는 그 인스턴스의 락을 일단 해제한다. 이것을 그림으로 나타내면 아래와 같다.
락을 취한 쓰레드 A 가 wait 메소드를 실행한다.
쓰레드 A는 wait 셋에 들어가 락을 해제한다.
쓰레드 B는 락을 설정할 수 있게 된다.
+. notify 메소드 - 쓰레드를 wait 셋에서 꺼낸다.
notify 메소드를 사용하면 wait 셋에 있는 쓰레드 한 개를 wait 셋에서 꺼낸다. 이 과정을 그림으로 나타내면 아래와 같다.
락을 취한 쓰레드 B가 메소드를 실행한다.
쓰레드 A가 wait 셋에서 나와 wait 다음 순서로 남어가려 하지만 notify 를 실행한 쓰레드 B가 아직 락을 가지고 있다.
notify를 실행한 쓰레드 B가 락을 해제한다.
wait 셋에서 나온 쓰레드 A가 락을 취하고 wait 다음 순서로 넘어간다.
notify 메소드를 실행했을 때 wait 셋에서 대기 중인 쓰레드가 여러개라고 하자. 이 때 어느 쓰레드가 선택될지는 정해져 있지 않다. 제일 먼저 wait 한 쓰레드가 선택될지 무작위로 선택될지 그 밖의 방법으로 선택될지는 Java 처리계에 따른다. 그러므로 선택된 쓰레드에 의존하여 프로그램을 작성하는 것은 바람직하지 않다. |
+. notifyAll 메소드 - 모든 쓰레드를 wait 셋에서 꺼낸다.
notifyAll 메소드를 사용하면 wait 셋에 있는 모든 쓰레드를 wait 셋에서 꺼낸다. -> 하지만 이 말이 모든 쓰레드가 수행을 시작한다는 의미는 아니다. 락은 이미 notifyAll 을 호출한 쓰레드가 가지고 있으므로 notifyAll 호출 쓰레드가 락을 해제할 때까지 블락된 상태가 된다. 락이 해제된 후, wait 셋에 있는 쓰레드들 중 락을 취한 쓰레드만이 수행을 재개한다.
notifyAll 을 호출하여 wait 셋에 있는 쓰레드들을 깨운다.
Wait 셋에서 깨어난 쓰레드는 인스턴스의 락을 취하기 위해 블락된다.
notiffyAll을 호출한 쓰레드가 락의 소유권을 해제한다.
블락되어 있는 쓰레드들 중 락을 소유한 쓰레드만이 수행을 재개한다.
다시 다음과 같이 wait 셋이 구성 될 것이다.
notify 메소드와 notifyAll 메소드는 많이 비슷하다. 그렇다면 어느 쪽을 써야 할까? 쉽지 않은 선택이다. notify 가 notifyAll 보다 빠르다. 깨울 쓰레드가 적기 때문이다. 그러나 notify 를 사용할 경우 이용 방법에 따라 프로그램이 멈출 위험이 있다. 일반적으로 notifyAll 을 사용한 쪽이 notify 를 사용한 쪽보다 코드가 견고해진다. 그러니까 프로그래머가 코드의 의미와 한계를 충분히 이해하고 있는 경우가 아니라면 notifyAll 을 사용하는 편이 낫다. |
+. wait, notify, notifyAll 은 Object 클래스의 메소드
wait, notify, notifyAll 의 동작을 떠올려 보자.
- obj.wait 은 obj의 wait 셋에 현재의 쓰레드를 넣는다.
- obj.notify 는 obj의 wait 셋에서 1개의 쓰레드를 깨운다.
- obj.notifyAll 은 obj 의 wait 셋에 있는 모든 쓰레드를 깨운다.
참고 : Java 언어로 배우는 디자인 입문 : 멀티쓰레드편