조컴퓨터

200908 OOP 13 - Java 객체지향 프로그래밍 (Ⅱ) 본문

자바 웹개발자 과정/JAVA

200908 OOP 13 - Java 객체지향 프로그래밍 (Ⅱ)

챠오위 2020. 9. 9. 00:17

예외 처리 Exception 

자바 클래스 실행(run)시 발생하는 오류. 그러나 코딩 상의 오류는 아니다. 

 

이러한 오류는

① try ~ catch문

   - 예상했던 예외가 발생하면 해당 예외 객체를 잡아(catch)내어 원하는 동작을 수행하고

     프로그램이 종료되지 않고 계속 진행할 수 있도록 하는 것

 throws문

   - 예외를 처리하기 보다는 발생한 예외 객체를 양도하는 것

   - 현재 메소드에서 예외 처리를 하기가 조금 어려운 상태일 때 현재 영역을 호출해 준 곳으로

     발생한 예외 객체를 대신 처리해 달라며 양도하는 것

 finally문

   - 예외가 발생하거나, 발생하지 않거나 무조건 수행하는 부분

으로 메세지를 확인할 수 있다. 

 

 

1) 예외 처리를 하지 않은 경우

 

System.out.println(1);
System.out.println(2/0);	//ArithmeticException발생
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

결과값이 나오지 않고 오류가 나타나는 것을 확인할 수 있다.

Exception이 발생하면 프로그램이 정상적으로 종료되지 않는다.

 

 

 

① try ~ catch문

2) 예외 처리를 한 경우

이 경우에는 Exception이 발생하더라도 정상적으로 프로그램을 종료시킬 수 있다.

기본 형식 : try { } catch( ) { }

 

try {
	//예외 발생이 예상되는 코드 작성
	System.out.println(1);
	System.out.println(2/0);
	System.out.println(3);
			
} catch(ArithmeticException e) {
	//예외가 발생되었을 경우 처리할 코드 작성
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

1은 정상적으로 출력이 되는데, 다음 결과값이 나오지 않고 오류가 나타나는 것을 확인할 수 있다.

그러나 try ~ catch문은 Exception이 발생했어도 프로그램이 원활히 종료되었기 때문에 END가 출력되었다.

 

 

 

3) ArrayIndexOutOfBoundsException

 

try {
	System.out.println(1);
	int[] num=new int[3];
	num[5]=7;
	System.out.println(2);
    
}catch (ArrayIndexOutOfBoundsException e) {
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

 

 

4) NumberFormatException

 

try {
	System.out.println(1);
	int num=Integer.parseInt("KOREA");	 //string -> int 변수 
	System.out.println(2);
    
}catch (NumberFormatException e) {		//형변환이 잘못되었다는 예외처리
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

 

5) NullPointerException

 

try {
	System.out.println(1);
	Integer inte=null;
	System.out.println(2/inte);
    
}catch (NullPointerException e) {
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

 

6) 다중 catch문

catch문도 중첩하여 사용할 수 있다.

 

try {
	int a=2/0;
	int b=Integer.parseInt("KOREA");
	int[] num=new int[3];
	num[5]=7;
    
}catch (ArithmeticException e) {
	System.out.println(e);
    
}catch (NumberFormatException e) {
	System.out.println(e);
    
}catch (ArrayIndexOutOfBoundsException e) {
	System.out.println(e);
    
}catch (NullPointerException e) {
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

여기서 자주 사용하는 Exception의 종류는 대략 10가지이다.

 

 

 

7) 다형성을 이용한 예외 처리

 

try {
	int a=2/0;
	int b=Integer.parseInt("KOREA");
	int[] num=new int[3];
	num[5]=7;
    
}catch (Exception e) {	//다형성
	//Exception 모든 예외 발생의 조상 클래스
	System.out.println(e);
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

 

③ finally문

   → 예외가 발생하거나, 발생하지 않거나 무조건 실행

 

try {
	System.out.println("OPEN");
	System.out.println(2/0);
			
}catch (Exception e) {
	System.out.println(e);
    
}finally {
	System.out.println("CLOSE");
    
}//end
System.out.println("END");

 

위의 코딩의 결과값은 다음과 같다.

 

 

 

 

② throws문

메소드 호출시 예외 처리를 한꺼번에 모아서 처리

 

class Test{
	//1)try~catch를 직접 이용한 예외처리
	/*
	public void view() {
		try {
			int a=3/0;
		}catch (Exception e) {}//end
	}//view() end
	public void disp() {
		try {
			int a=Integer.parseInt("KOREA");
		}catch (Exception e) {}
	}//disp() end
	*/
	
	//2)throws를 이용한 예외처리
	public void view() throws Exception{	
		int a=3/0;
	}//view() end
	public void disp() throws NumberFormatException, NullPointerException {
		int a=Integer.parseInt("KOREA");
	}//disp() end
	
	//OS가 개입해서 문제가 발생하지 않도록 조정하는 기법
	public synchronized void login() {}
	
	
}//class end


public class Test02_throws {
	public static void main(String[] args) {
		//throws문
		//메소드 호출시 예외처리를 한꺼번에 모아서 처리
		
		try {
			Test test=new Test();
			test.view();
			test.disp();
            
		} catch (Exception e) {
			System.out.println(e);
		}//end

	}//main() end
}//class end

 

 

 

 

내부 클래스 Inner class

클래스 내부에서 선언된 클래스

내부 클래스는 외부 클래스의 모든 멤버들을 마치 자신의 멤버처럼 사용할 수 있다.

내부에서 사용하려고 만든 클래스이기 때문에 외부에서도 사용할 수는 있다. 하지만 비추천한다.

static 내부 클래스를 제외하고는 다른 내부 클래스는 항상 외부 클래스를 통해야 생성할 수 있다.

 

1) Member 내부 클래스

- 객체를 생성해야만 사용할 수 있는 멤버들과 같은 위치에 정의되는 클래스

- 내부 클래스를 생성하려면 외부 클래스의 객체를 생성한 후 생성할 수 있다.

 

   class Outer {

          ...

          class Inner {

          }

          ...

   }

 

   class Outer {

          ...

          public void methodA( ) {

                   class Inner {

                   }

          } //멤버 메소드

          ...

   }

 

2) Static 내부 클래스

- 내부 클래스가 아니라 할 수 있으며, 외부 클래스를 거치지 않고도 접근할 수 있다.

- 최상위 클래스

- 내부 클래스 안에 static 변수를 가지고 있다면 해당 내부 클래스는 static으로 선언해야 한다.

- 외부 클래스를 생성하지 않고도 외부 클래스명.내부 클래스 생성자( )로 생성할 수 있다.

 

   class Outer {

          ...

          static class Inner {

          }

          ...

   }

 

 

예제1) 내부 클래스

 

import oop0908.WebProgram.Language;
import oop0908.WebProgram.Smart;

class WebProgram{	//.jsp(Spring Framework) .php .asp .py(Django Framework)
	
	String title="Java Program";
	
	class Language{	//inner class
		String basic="JAVA, HTML, CSS, JavaScript";
		void display() {
			System.out.println("기초수업:"+basic);
		}
	}//class end
    
	class Smart{	//inner class
		String basic="Objective-C, Java OOP, C#";
		void display() {
			System.out.println("기초수업:"+basic);
		}
	}//class end
	
	public void print() {
		Language lang=new Language();
		lang.display();
		
		Smart sm=new Smart();
		sm.display();
	}//print() end
}//class end


public class Test03_inner {
	public static void main(String[] args) {
		//내부 클래스 inner class
		//->클래스 내부에서 선언된 클래스
		
		WebProgram web=new WebProgram();
		web.print();
		
		/*
		 	기초수업:JAVA, HTML, CSS, JavaScript
			기초수업:Objective-C, Java OOP, C#
		*/
		
		//에러. 내부클래스는 직접 접근할 수 없다.
		//Language lang=new Language();
		//Smart sm=new Smart();
		
		//내부클래스는 외부에서 단계적으로 접근할 수는 있다.
		Language lang=new WebProgram().new Language();
		Smart sm=new WebProgram().new Smart();
        
		lang.display();
		sm.display();

	}//main() end
}//class end

 

위의 코딩의 결과값은 다음과 같다.

 

 

안드로이드기반 자바 코딩에서의 Inner class 사용 (R 클래스)

 

class R{
	static class id{
		static String btn="버튼";
	}
}//class end

public class Test03_inner {
	public static void main(String[] args) {
		
        System.out.println(R.id.btn);

	}//main() end
}//class end

//버튼

 

 

 

 

Java Collection Framework

자바에서 컬렉션 프레임워크는 다수의 데이터를 쉽고 효과적으로 처리할 수 있도록 표준화된 방법을 제공하는 클래스의 집합을 의미한다. 즉, 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것을 말한다. 컬렉션 프레임워크는 자바의 인터페이스를 사용하여 구현된다.

 

1) 개요

- java.util.*

- 객체를 수집하여 저장해 두었다가 요청이 있을 시 저장소에서 추출하여 제공하는 것을 목적으로 한다.

- 배열의 단점을 개선한 클래스로 객체만 저장할 수 있다.

- int 등 각종 기본 데이터 타입을 저장하려면 Integer Wrapper Class 등으로 변환해서 사용해야 한다. (→ 오토박싱 가능)

- 배열의 크기는 변경이 불가능하나 ArrayList, Vector는 동적인 크기 변경이 가능하다.

 

2) Collections Framework의 핵심 인터페이스

 

- List : 순서(Index)가 있다.

         데이터의 중복을 허용

         배열 기반. 순서를 유지. 중복 허용. 매개 변수가 중요

         Vector, List, ArrayList, Iterator, Collections, Collectors 등

 

- Set : 순서가 없다.

         중복 허용 안함

         Set, HashSet 등

 

- Map : 순서가 없다. key와 value가 있다.

          key 중복 불가능. value 중복 가능

          우편번호, 지역번호

          Map, HashMap, HashTable, Properties 등

 

 

인터페이스의 상속 관계

 

컬렉션 최상위 클래스 Collection 인터페이스

 

 

참고) 

1) ccm3.net/archives/20745

 

[Java] 자바의 컬렉션 프레임워크(Collection Framework)에 대한 이해 (1) – GRINBI

♦ 자바의 컬렉션 프레임워크(Collection Framework) 자바에 컬렉션 프레임워크는 다수의 데이터를 쉽고 효과적으로 처리할 수 있도록 표준화된 방법을 제공하는 클래스의 집합을 의미한다. 즉, 데이�

ccm3.net

2) www.javatpoint.com/collections-in-java

 

Collections in Java - javatpoint

Collections in java or collection framework in java with List, Set, Queue and Map implementation, hierarchy and methods of Java Collections framework, ArrayList, LinkedList, HashSet, LinkedHashSet, TreeSet, HashMap, LinkedHashMap, TreeMap, PriorityQueue, A

www.javatpoint.com

3) tcpschool.com/java/java_collectionFramework_concept

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

interface List{}
class Vector implements List{}
class ArrayList implements List{}
			
interface Set{}
class HashSet implements Set{}
			
interface Map{}
class HashMap implements Map{}
			
Vector vec=new Vector()
List vec=new Vector()		//다형성
List list=new ArrayList()	//다형성
			
Set set=new HashSet()		//다형성
Map map=new HashMap()		//다형성

 

 

예제1) List 계열

 

//Element 요소		
Vector vec=new Vector();
vec.add(3);
vec.add(2.4);
vec.add('R');
vec.add("KOREA");
vec.add(new Integer(5));
//Integer inte=new Integer(5)	//old version
//Integer inte=5		//new version
	
vec.add(new String("SEOUL"));
//String str=new String("SEOUL")
//String str="SEOUL"
		
//요소의 갯수
System.out.println(vec.size());	//6
		
for(int i=0; i<vec.size(); i++) {
	System.out.println(vec.get(i));
}//for end
		
/*
	3
	2.4
	R
	KOREA
	5
	SEOUL
*/

 

//0번째 요소 제거
vec.remove(0);
System.out.println(vec.size());
		
//vec요소 전부 제거
vec.removeAllElements();
		
if(vec.isEmpty()) {	//요소의 갯수가 0개인지?
	System.out.println("요소 없다");
}else {
	System.out.println("요소 있다");
}//if end
		
//요소 없다

 

 

예제1-2) remove( ) 메소드를 이용해서 다음의 list 요소를 전부 삭제하시오.

 

List list=new ArrayList(); //다형성
list.add(5);
list.add(6.7);
list.add('r');
list.add("JEJU");
list.add(new Character('B'));

 

내 답안

 

//System.out.println(list.size());	//5
		
for(int i=0; i<list.size(); i++) {
	list.remove(i);
	i--;
}//for end
		
System.out.println(list.size());//0

 

선생님 답안

 

for(int i=list.size()-1; i>=0; i--) {
	list.remove(i);
}//for end
		
System.out.println(list.size());//0

 

※ remove( ) 메소드를 통해 요소를 삭제할 경우, 그 요소가 없어진 자리를 바로 다음 요소가 차지하기 때문에 해당 위치의 요소는 삭제되지 않는다.

 

 

 

예제2) SetMap 계열

 

//Set 계열: 순서가 없다
Set set=new HashSet();	//다형성
set.add(3);
set.add(2.4);
set.add("BUSAN");
set.add(new Integer(5));
set.add('R');
		
//System.out.println(set.size());	//5
		
//cursor : 가리킬 요소가 있으면 true, 없으면 false값 반환
//cursor를 이용해서 요소를 접근하는 경우
Iterator iter=set.iterator();
while(iter.hasNext()) {	//다음 cursor가 존재하는지? -> boolean형
	//cursor가 가리키는 요소 가져오기
	Object obj=iter.next();
	System.out.println(obj);
}//while end

/*
	2.4
	R
	3
	BUSAN
	5
*/

 

 

예제3) Map 계열

 

//Map 계열: 순서가 없다
//->Key  : 이름표. 중복 허용하지 않음
//->Value: 값.    중복 허용
		
HashMap map=new HashMap();
map.put("one", "박지성");		//map.put(Object key, Object value)
map.put("two", 3);	
map.put("three", new Double(2.4));
		
//System.out.println(map.size());	//3
		
System.out.println(map.get("one"));	//박지성
System.out.println(map.get("two"));	//3
System.out.println(map.get("three"));	//2.4
		
//key는 중복선언이 가능하다
map.put("one", "손흥민");
System.out.println(map.get("one"));	//손흥민
		
//value는 중복이 가능하다
map.put("four", 3);
System.out.println(map.get("four"));	//3

 

 

문제1) 문자를 기준으로 문자열을 분리해서 앞의 문자열은 key, 뒤의 문자열은 value로 Map 저장하고

         key값으로 "read.do" 호출하면 value값으로 "net.bbs.Read" 출력하시오.

 

내 답안 

 

HashSet command=new HashSet();
command.add("list.do=net.bbs.List");
command.add("read.do=net.bbs.Read");
command.add("write.do=net.bbs.Write");
		
HashMap map=new HashMap();
		
		
Iterator iter=command.iterator();
		
while(iter.hasNext()) {
	String str=(String) iter.next();
	StringTokenizer sent=new StringTokenizer(str, "=");
			
	while(sent.hasMoreTokens()) {
		String key=sent.nextToken();
		String value=sent.nextToken();
		map.put(key, value);
	}//while end
			
}//while end

System.out.println(map.get("list.do"));	//net.bbs.List

 

선생님 답안

 

HashSet command=new HashSet();
command.add("list.do=net.bbs.List");
command.add("read.do=net.bbs.Read");
command.add("write.do=net.bbs.Write");
		
HashMap map=new HashMap();
        
        
//1)커서 생성하기
Iterator iter=command.iterator();
		
//2)커서가 있을 때까지 반복
while(iter.hasNext()) {

	//3)커서가 가리키는 요소를 가져와서 문자열 형변환
	Object obj=iter.next();
	String str=(String) obj;//다형성
	//System.out.println(str);
			
	//4)"="의 위치 파악
	int pos=str.indexOf("=");
	String key=str.substring(0, pos);
	String value=str.substring(pos+1);
			
	//5)map에 저장하기
	map.put(key, value);
			
}//while end
 
System.out.println(map.get("list.do")); //net.bbs.List

 

 

 

 

Generics 제네릭스

- 객체를 저장하는 기술인 Collection Framework의 단점을 개선한 기능

 

Vector vec=new Vector();
vec.add(123);
vec.add("sky");
int[3] a={1,2,3};

  

- 데이터 자료형인 String, Integer과 같은 형태를 처음에 정해 놓지 않고

  임의의 타입으로 명시해 준 후에 나중에 직접적으로 해당 구문을 사용할 때 지정하는 형태

- Class ArrayList에서 'E'가 있는 곳에는 ArrayList를 선언하고 생성할 때 사용할 실제 참조 자료형이 들어간다.

 

- E는 Element(원소)를 말하며, new ArrayList( )이면 'E'는 'String' 클래스를 가리키며,

  <> 안의 String은 유형 매개 변수(type parameter)이다.

  따라서 boolean add(Object o) 매소드는 boolean add(String o)가 된다.

- 'E'는 ArrayList의 인스턴스를 만들 때 <> 안에 넣는 타입을 말한다.

- 'E'는 컬렉션에 저장하고 컬렉션에서 리턴할 원소의 타입을 가리킨다.

 

 

형식) 

       class 클래스명 <제네릭타입>

       {

                 ~~~

       }

 

* int형만 num 변수에 대입 가능하다.

 

int[] num=new int[3];

 

제네릭스 굿

 

 

참조)

1) tcpschool.com/java/java_generic_concept

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

2) yaboong.github.io/java/2019/01/19/java-generics-1/

 

자바 제네릭 이해하기 Part 1

개요 제네릭이란? 제네릭을 사용하는 이유 제네릭을 사용할 수 없는 경우 제네릭 메서드란? 제네릭 타입 제한하기 (Bounded Type Parameter)

yaboong.github.io

3) medium.com/@joongwon/java-java%EC%9D%98-generics-604b562530b3

 

[ Java] Java의 Generics

Java 언어에서 언어적으로 가장 이해하기 어렵고 제대로 사용하기가 어려운 개념이 Generics가 아닐까 싶다. 평소에 클래스나 인터페이스 설계 시 Generics를 자주 사용하긴 했지만 어떠한 계기로 인�

medium.com

 

 

예제1) Vector

 

//Vector<int> 기본자료형은 올 수 없다. 에러
Vector<String> vec=new Vector<String>();
vec.add("개나리");
vec.add(new String("진달래"));
vec.add(new String("무궁화"));
//vec.add(3);			//에러
//vec.add(new Integer(5));	//에러
				
for(int i=0; i<vec.size(); i++) {
	String str=vec.get(i);
	System.out.println(str);
}//for end

/*
	개나리
	진달래
	무궁화
*/

 

 

예제2) ArrayList

 

ArrayList<Integer> list=new ArrayList<Integer>();
list.add(3);	//기본형이 자동으로 참조형화 된다(autoboxing)
list.add(new Integer(5));
//list.add("");	//에러
//list.add(2.4);//에러
				
for(int i=0; i<list.size(); i++) {
	Integer str=list.get(i);
	System.out.println(str);
}//for end

/*
	3
	5
/

 

 

예제3) HashSet

 

HashSet<String> set=new HashSet<String>();
set.add("개나리");
set.add("진달래");
set.add("라일락");
        
Iterator<String> iter = set.iterator();
while(iter.hasNext()) {
	System.out.println(iter.next());
}//while end

/*
	라일락
	진달래
	개나리
*/

 

※ Set에는 인덱스로 객체를 가져오는 get(index) 메소드가 없다.

   대신 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자(Iterator)를 제공한다.

 

 

예제4) HashMap

1) entrySet( ).iterator( )

 

HashMap<String, Integer> map=new HashMap<String, Integer>();
map.put("one", 3);
map.put("two", new Integer(5));
		
//1) entrySet().iterator()
Iterator<Map.Entry<String, Integer>> entries = map.entrySet().iterator();
while(entries.hasNext()) {
	Map.Entry<String, Integer> entry = entries.next();
	System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());;
}//while end
		
/*
	key:one value:3
	key:two value:5
*/

 

2) keySet( ).iterator( )

 

HashMap<String, Integer> map=new HashMap<String, Integer>();
map.put("one", 3);
map.put("two", new Integer(5));
        
//2) keySet().iterator()
Iterator<String> keys = map.keySet().iterator();
while(keys.hasNext()) {
	String key = keys.next();
	System.out.println("key:" + key + " value:" + map.get(key));
}//while end
        
/*
	key:one value:3
	key:two value:5
*/

 

 

예제5) ArrayList (*2 classes)

 

class Mountain{
	String name;	//산이름
	int height;		//산높이
	
	public Mountain() {}
	public Mountain(String name, int height) {
		this.name = name;
		this.height = height;
	}
}//class end

public class ArrayList_mt {
	public static void main(String[] args) {

		Mountain one   =new Mountain("한라산", 1950);
		Mountain two   =new Mountain("관악산", 1500);
		Mountain three =new Mountain("북한산", 1000);
				
		ArrayList<Mountain> items=new ArrayList<Mountain>();
		items.add(one);
		items.add(two);
		items.add(three);
		//items.add("SOLDESK"); //에러
				
		for(int i=0; i<items.size(); i++) {
			Mountain dto=items.get(i);
			System.out.print("산이름:" + dto.name);
			System.out.println(" 산높이:" + dto.height);
		}//for end
        
	}//main() end
}//class end  

/*
	산이름:한라산 산높이:1950
	산이름:관악산 산높이:1500
	산이름:북한산 산높이:1000
*/

 

참고)

1) coding-factory.tistory.com/554

 

[Java] 자바 HashSet 사용법 & 예제 총정리

HashSet이란? HashSet은 Set 인터페이스의 구현 클래스입니다. 그렇기에 Set의 성질을 그대로 상속받습니다. Set은 객체를 중복해서 저장할 수 없고 하나의 null 값만 저장할 수 있습니다. 또한 저장 순�

coding-factory.tistory.com

2) coding-factory.tistory.com/556

 

[Java] 자바 HashMap 사용법 & 예제 총정리

HashMap 이란? HashMap은 Map 인터페이스를 구현한 대표적인 Map 컬렉션입니다. Map 인터페이스를 상속하고 있기에 Map의 성질을 그대로 가지고 있습니다. Map은 키와 값으로 구성된 Entry객체를 저장하는

coding-factory.tistory.com

3) java2blog.com/hashmap-in-java-with-examples/

 

Java HashMap - HashMap in java | Java2Blog

Learn about HashMap, its important methods, how to iterate over HashMap, thread safety issues with Hashmap and how to make it synchronized.

java2blog.com

 

 

 

 

Thread 스레드

 

- 프로세스 process : 운영체제에서 실행 중인 하나의 애플리케이션

- 운영체제는 멀티 태스킹*을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킨다.

  예시) 워드로 문서 작업을 하면서 동시에 유튜브 영상을 재생

 

* 멀티 태스킹 multi tasking : 두 가지 이상의 작업을 동시에 처리하는 것

 

- 멀티 스레드 multi thread : 하나의 프로세스가 두 가지 이상의 작업을 처리

  예시) 카카오톡으로 사람과 대화를 나누면서 동시에 그 사람에게 사진을 전송

 

- 스레드 thread : 운영체제가 독립적으로 처리하는 하나의 작업 단위

                       프로세스 내에서 실행되는 흐름의 단위

                       하나의 프로그램이나 하나의 메소드가 CPU 자원을 전부 점유하는 것을 막을 수 있다.

  예시) 2020년도 현재 CPU 시장은 16 코어 32 스레드. 

         AMD 3세대 쓰세요. 가성비 짱

 

따라서 스레드는 여러 가지 작업을 동시에 수행할 수 있게 한다.

 

 

예제1) Thread를 사용하지 않는 경우

 

package oop0908;

class MyThread1{
	//field 멤버변수
	private int num;
	private String name;
	//constructor 생성자함수
	public MyThread1() {}//기본생성자 함수
	public MyThread1(int num, String name) {
		this.num = num;		//this.멤버변수=지역변수
		this.name = name;
	}
	
	//method 멤버함수
	public void start() {
		run();
	}//start() end
	
	public void run() {
		for(int a=0; a<num; a++) {
			System.out.println(name+":"+a);
		}//for end
	}//run() end
	
}//class end


public class Test07_thread {
	public static void main(String[] args) {
		//Thread 클래스
		//->하나의 프르그램이나 하나의 메소드가 CPU 자원을
		//->전부 점유하는 것을 막을 수 있다.
		
		//1)Thread를 사용하지 않은 경우
		MyThread1 t1=new MyThread1(1000, "★");
		MyThread1 t2=new MyThread1(1000, "★★");
		MyThread1 t3=new MyThread1(1000, "★★★");
		
		t1.start();
		t2.start();
		t3.start();

	}//main() end
}//class end

 

결과값

★:0 
★:1 
★:2 
★:3

...

★★★:998 
★★★:999 

 

 

 

예제2) Thread를 사용하는 경우

 

package oop0908;

class MyThread2 extends Thread{
	//클래스가 클래스를 상속받는 경우 단일 상속만 가능하다
	private int num;
	private String name;
	public MyThread2() {}//기본생성자 함수
	public MyThread2(int num, String name) {
		this.num = num;		//this.멤버변수=지역변수
		this.name = name;
	}

	//start()함수는 run()함수를 호출하는 기능
		
	@Override
	public void run() {
		for(int a=0; a<num; a++) {
			System.out.println(name+":"+a);
		}//for end
	}//run() end
		
}//class end


public class Test08_Thread {
	public static void main(String[] args) {
		//2)Thread를 사용하는 경우
		//->JVM이 쓰레드 관리자에 등록하고
		//->start() 메소드가 run()을 호출한다
		//->예)채팅 프로그램, 실시간 예매 등에서 많이 사용한다
		
		MyThread2 t1=new MyThread2(1000, "★");
		MyThread2 t2=new MyThread2(1000, "★★");
		MyThread2 t3=new MyThread2(1000, "★★★");
		
		t1.start();
		t2.start();
		t3.start();
		
	}//main() end
}//class end

 

결과값

★:0
★★★:0
★★:0
★★★:1

...

★:998
★:999

 

뒤섞인 결과값이 나타난다.

 

 

 

예제3) Runnable 인터페이스를 이용하는 경우

 

package oop0908;

class MyThread3 implements Runnable {
	private int num;
	private String name;
	public MyThread3() {}//기본생성자 함수
	public MyThread3(int num, String name) {
		this.num = num;		//this.멤버변수=지역변수
		this.name = name;
	}
	
	@Override
	public void run() {
		for(int a=0; a<num; a++) {
			System.out.println(name+":"+a);
		}//for end
	}
	
}//class end


public class Test09_Thread {
	public static void main(String[] args) {
		//3)Runnable 인터페이스를 이용한 경우
		/*
			 Interface Runnable{}
			 class Thread implements Runnable{}
		*/
		
		Thread t1=new Thread(new MyThread3(1000, "★"));
		Thread t2=new Thread(new MyThread3(1000, "★★"));
		Thread t3=new Thread(new MyThread3(1000, "★★★"));
		
		t1.start();
		t2.start();
		t3.start();
		
	}//main() end
}//class end

 

결과값

★:0
★★:0
★★★:0
★★:1
★:1

...

★:997
★:998
★:999

 

 

 

문제) 영화 티켓 구매

 

synchronized 키워드

Java에서 제시하는 멀티 스레드 프로그래밍에서의 동기화 문제 해결 방안이다.

이때 synchronized 메소드는 자신이 포함된 객체에 lock을 건다.

 

즉, 메소드에 synchronized 키워드를 지정하면 특정 스레드에 의하여 그 메소드가 실행되는 도중에 다른 스레드가 그 메소드를 호출할 수 없다. 

 

다음 식은 해당 메소드를 이용하여 작성한 것이다.

 

package oop0908;

class Data {
	private int movieTicket=0;	//좌석번호
	
	public synchronized String ticket() {
		String str="";
		if(movieTicket<100) {
			movieTicket=movieTicket+1;
			str="영화 예약 번호:"+movieTicket;
		}//if end
        
		return str;		
	}//ticket() end
	
	public synchronized int getMovieTicket() {	//티켓 100장
		return movieTicket;
	}//getMovieTicket() end
	
}//class end


public class Test10_TicketTest extends Thread{
	
	String where; //현장구매, 인터넷, 모바일
	Data data;
	
	public Test10_TicketTest() {}
	public Test10_TicketTest(String where, Data data) {
		this.where=where;
		this.data=data;
	}
		
	@Override
	public void run() {
		while(true) {
			//티켓은 10장만 판매
			if(data.getMovieTicket()>=150) break;  
			//좌석번호
            
			System.out.println(where+"-"+data.ticket());
		}//while end
		
	}//run() end
	
	public static void main(String[] args) {
		//현장구매, 인터넷, 모바일 실시간 예매
		Data data=new Data();
		
		Test10_TicketTest ticket1=new Test10_TicketTest("현장구매", data);
		Test10_TicketTest ticket2=new Test10_TicketTest("인터넷", data);
		Test10_TicketTest ticket3=new Test10_TicketTest("모바일", data);
		
		ticket1.start();
		ticket2.start();
		ticket3.start();

	}//main() end
}//class end

 

결과값(movieTicket<100)

모바일-영화 예약 번호:1
현장구매-영화 예약 번호:2
인터넷-영화 예약 번호:3
현장구매-영화 예약 번호:5
모바일-영화 예약 번호:4
현장구매-영화 예약 번호:7
인터넷-영화 예약 번호:6
현장구매-영화 예약 번호:9

...

인터넷-영화 예약 번호:96
인터넷-영화 예약 번호:97
인터넷-영화 예약 번호:98
인터넷-영화 예약 번호:99
인터넷-영화 예약 번호:100

 

 

 

synchronized 키워드 참고)

pangtrue.tistory.com/214

 

[Java] synchronized 키워드

Java는 멀티 스레드 프로그래밍에서의 동기화 문제에 대해 3가지 방법을 제시한다. synchronized 키워드 volatile 변수 Atomic 클래스 이 세가지 중에서 synchronized 키워드에 대해 정리해보자. synchronized 키.

pangtrue.tistory.com