단일 프로세스와 멀티 프로세스:
단일 프로세스는 하나의 프로세서가 하나의 작업을 수행하는 것을 의미합니다.
멀티 프로세싱은 '두 개 이상, 다수의 프로세서가 협력적으로 작업을 동시에 처리하는 것’을 의미합니다.
프로세스와 쓰레드의 차이점:
프로세스는 실행될 때 운영체제로부터 프로세서, 필요한 주소 공간, 메모리 등 자원을 할당받습니다.
스레드는 한 프로세스 내에서 동작되는 여러 실행의 흐름으로 프로세스 내의 주소 공간이나 자원들을 같은 프로세스 내에 스레드끼리 공유하면서 실행됩니다.
for(int i=0; i < 300; i++)
System.out.printf("%s", new String("-"));
for(int i=0; i < 300; i++)
System.out.printf("%s", new String("|"));
class HorizontalThread extends Thread {
public void run() {
for(int i=0; i < 300; i++)
System.out.printf("%s", new String("-"));
}
}
class VerticalThread extends Thread {
public void run() {
for(int i=0; i < 300; i++)
System.out.printf("%s", new String("|"));
}
}
public static void main(String[] args) {
HorizontalThread horizontalThread = new HorizontalThread();
VerticalThread verticalThread = new VerticalThread();
horizontalThread.start();
verticalThread.start();
}
메인 스레드가 종료되더라도 실행 중인 스레드가 하나라도 있다면 프로세스는 종료되지 않습니다.
이 문장은 멀티 스레드 애플리케이션에서 메인 스레드가 종료되더라도 다른 스레드가 아직 실행 중이라면 프로세스가 종료되지 않는다는 것을 의미합니다.
main(){
ThreadCount threadCount = new ThreadCount();
threadCount.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은 " + input + "입니다.");
}
=============================================
10 9 8 7 6 ... 이 1초마다 실행 되도록 쓰레드를 완성하시오.
import javax.swing.JOptionPane;
class ThreadCount extends Thread {
public void run() {
// Implement the thread's behavior here
}
}
public static void main(String[] args) {
ThreadCount threadCount = new ThreadCount();
threadCount.start();
String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
System.out.println("입력하신 값은 " + input + "입니다.");
}
임계 영역이란 둘 이상의 프로세스와 스레드가 공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 코드 영역을 말합니다. 여기서 공유 자원이란 각 프로세스와 스레드가 함께 접근할 수 있는 파일, 데이터 등의 자원이나 변수 등을 의미합니다.
synchronized 키워드는 Java에서 동기화를 구현하는데 사용됩니다. 이 키워드는 어떤 객체에서도 특정 문장 블록에 대해 lock 설정을 할 수 있습니다. 즉, 한 번에 하나의 스레드만이 해당 코드 블록을 실행할 수 있도록 합니다.
프로세스 메모리 구조
-------------------
| 코드 영역 |
-------------------
| 데이터 영역 |
-------------------
| 힙 영역 |
-------------------
| 스레드 1 스택 |
-------------------
| 스레드 2 스택 |
-------------------
| ... |
-------------------
| 스레드 N 스택 |
-------------------
Thread-0:1번
Thread-0:1번
Thread-2:3번
Thread-2:3번
Thread-1:2번
Thread-1:2번
Thread-4:5번
Thread-4:5번
Thread-3:4번
Thread-3:4번
class StringPrint{
synchronized void display(String s) {
for(int i = 1; i <= 2; i++) {
System.out.print(Thread.currentThread().getName() + ":");
System.out.print(s);
System.out.println();
}
System.out.println();
}
}
class PrintThread extends Thread{
private StringPrint sp;
private String str;
public PrintThread(String s , StringPrint sp) {
this.str = s;
this.sp = sp;
}
@Override
public void run() {
sp.display(str);
}
}
=======================================
public static void main(String[] args) {
StringPrint sp = new StringPrint();
Thread th1 = new PrintThread("1번", sp);
Thread th2 = new PrintThread("2번", sp);
Thread th3= new PrintThread("3번", sp);
Thread th4 = new PrintThread("4번", sp);
Thread th5 = new PrintThread("5번", sp);
th1.start();
th2.start();
th3.start();
th4.start();
th5.start();
===================================
public static void main(String[] args) {
StringPrint sp = new StringPrint();
Thread[] threads = new Thread[5];
threads[0] = new PrintThread("1번", sp);
threads[2] = new PrintThread("3번", sp);
threads[1] = new PrintThread("2번", sp);
threads[4] = new PrintThread("5번", sp);
threads[3] = new PrintThread("4번", sp);
for (Thread thread : threads) {
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Accout{
private int balance = 1000;
public int getBalance() {
return balance;
}
public void withdraw(int money) throws Exception {
if(balance >= money) { //300
Thread.sleep(1000); // 다른 쓰레드한테 CPU 양보
balance = balance - money;
}
}
}
class AccountThread implements Runnable{
Accout accout = new Accout();
@Override
public void run() {
while(accout.getBalance() > 0) { //1000
// 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
int money = (int)(Math.random() * 3 + 1) * 100; //300
try {
accout.withdraw(money);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("balance:"+accout.getBalance()); //-100 이 찍힘
}
}
}
main 메소드
=======================
Runnable r = new AccountThread();
new Thread(r).start();
new Thread(r).start();
public synchronized void withdraw(int money) throws Exception {
if(balance >= money) { //300
Thread.sleep(1000); // 다른 쓰레드한테 CPU 양보
balance = balance - money;
}
}
HashMap<String, Integer> 컬렉션을 생성하고
“에스프레소”는 2000, “아메리카노”는 2500, “카푸치노”는 3000, “카페라테”는 3500을 저장하라.
그리고 다음과 같이 음료수 이름을 입력받으면 HashMap에서 검색하여 가격을 출력하라.
public class HashMapTest {
public static void main(String[] args){
HashMap<String, Integer> menu = new HashMap<>();
Scanner sc = new Scanner(System.in);
menu.put("에스프레소", 2000);
menu.put("아메리카노", 2500);
menu.put("카푸치노", 3000);
menu.put("카페라떼", 3500);
while (true){
try {
System.out.print("주문 > ");
String input = sc.nextLine();
if(input.equals("그만")){
break;
}
if(menu.get(input) == null){
System.out.println("없는 메뉴 입니다.");
}else {
System.out.println(input + "는 " + menu.get(input) + "원 입니다.");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public class HashMapTest {
public static void main(String[] args){
HashMap<String, Integer> menu = new HashMap<>();
Scanner sc = new Scanner(System.in);
menu.put("에스프레소", 2000);
menu.put("아메리카노", 2500);
menu.put("카푸치노", 3000);
menu.put("카페라테", 3500);
while (true){
try {
System.out.print("주문 > ");
String input = sc.nextLine();
if(input.equals("그만")){
break;
}
if(menu.get(input) == null){
System.out.println("없는 메뉴 입니다.");
}else {
System.out.println(input + "는 " + menu.get(input) + "원 입니다.");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}