-백그라운드로 작동하는 스레드
-일반스레드가 종료되면 데몬스레드는 자동 종료 됨
package thread;
import java.util.Scanner;
public class Thread2 {
public static void main(String[] args) {
Thread2 thr2 = new Thread2();
thr2.test2();
}
class SleepThread implements Runnable {
@Override
public void run() {
for(int i=1; i<=10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("[" + Thread.currentThread().getName() + "] " + i);
}
System.out.println(Thread.currentThread().getName() + " 끝!");
}
}
private void test2() {
Thread th = new Thread(new SleepThread(),"초시계스레드");
th.setDaemon(true);
th.start(); //일반 스레드: 글자 입력해도 실행되고 있음
System.out.println("아무 글자나 입력하시오: ");
String str = new Scanner(System.in).nextLine(); //한줄로 표현 가능
}
-다른 스레드에 IntteruptedException을 유발하여 종료/분기 처리 되도록 함
package thread;
import java.util.Scanner;
public class Thread2 {
public static void main(String[] args) {
Thread2 thr2 = new Thread2();
thr2.test3();
System.out.println(Thread.currentThread().getName() + " 끝!");
}
class SleepThread implements Runnable {
@Override
public void run() {
for(int i=1; i<=10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("인터럽트 발생. 스레드를 종료합니다.");
break;
}
System.out.println("[" + Thread.currentThread().getName() + "] " + i);
}
System.out.println(Thread.currentThread().getName() + " 끝!");
}
}
private void test3() {
Thread th = new Thread(new SleepThread(), "인터럽트스레드");
th.start();
System.out.println("엔터를 치면 인터럽트 스레드가 종료");
new Scanner(System.in).nextLine(); //변수에 저장해봤자 그 변수 안 쓰니까 이렇게 써도 됨
th.interrupt();
}
}
*연습문제*
package thread;
import java.util.Scanner;
//쌤이 쓴 코드
public class ThreadEx3 {
public static void main(String[] args) {
ThreadEx3 th = new ThreadEx3();
th.test1();
System.out.println(Thread.currentThread().getName() + "End!");
}
private void test1() {
Thread th1 = new Thread(new MultiplyThread(2,1000), "2배수쓰레드");
Thread th2 = new Thread(new MultiplyThread(3,2000), "3배수쓰레드");
th1.start();
th2.start();
System.out.println("엔터를 치면 종료됩니다");
new Scanner(System.in).nextLine();
th1.interrupt();
th2.interrupt();
// th1.setName("2배수쓰레드"); 쓰레드 이름을 나중에 설정할 때
}
class MultiplyThread implements Runnable {
private int num;
private int millis;
public MultiplyThread(int num, int millis) {
this.num = num;
this.millis = millis;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
int i = 1;
while(true) {
try {
System.out.println("[" + name + "]" + num*i++);
Thread.sleep(millis);
} catch (InterruptedException e) {
break;
}
}
}
}
}
=>
엔터를 치면 종료됩니다
[2배수쓰레드]2
[3배수쓰레드]3
[2배수쓰레드]4
[2배수쓰레드]6
[3배수쓰레드]6
[2배수쓰레드]8
[3배수쓰레드]9
[2배수쓰레드]10
[2배수쓰레드]12
[3배수쓰레드]12
[2배수쓰레드]14
[2배수쓰레드]16
[2배수쓰레드]18
[3배수쓰레드]15
[2배수쓰레드]20
mainEnd!
한 자원을 여러개의 스레드가 동시에 사용하지 못 하도록 함
나이를 수정하기도 전에 다른 스레드가 자원을 가지고 가려고 하면 수정하지 못 한채 종료되어버릴 수 있음
lock을 걸어, 내가 작업하는 동안 다른 스레드가 사용하지 못 하도록 함.
공유정보가 들어가있는 블록만 동기화 할 수도 있음.
재고량과 주문량이 맞지 않음. 그래서 동기화 시켜줌!
package thread;
public class Synchronized4 {
public static void main(String[] args) {
Synchronized4 sync = new Synchronized4();
sync.test1();
}
private void test1() {
Drink dk = new Drink(50000);
Thread thr = new Thread(new Delivery(dk), "kh지점");
Thread thr2 = new Thread(new Delivery(dk), "영등포지점");
Thread thr3 = new Thread(new Delivery(dk),"당산지점");
thr.start();
thr2.start();
thr3.start();
}
class Drink { //개수만큼 음료수 판매하는 클래스
public int stock;
Drink(int stock) { //재고물량이 몇 개인지, 생성자
this.stock = stock;
}
//★1. 메소드에 직접 동기화
//public synchronized void sale(int count) { 재고물량에서 몇 개를 판매할 건지 메소드
public void sale(int count) {
String name = Thread.currentThread().getName();
//★2. 동기화 블럭: 밑으로 다른 코드들도 많으면 블럭 활용이 좋음
synchronized(this) { //나 자신의 객체를 공유함
if(stock >= count) {
stock -= count;
System.out.printf("[%s] 주문 %d개 | 현재 재고 %d개 \n", name, count, stock);
} else {
System.out.println("재고가 부족합니다.");
}
}
}
}
class Delivery implements Runnable { //스레드 생성 클래스
private Drink drink;
Delivery(Drink drink) {
this.drink = drink;
}
@Override
public void run() {
while(drink.stock > 0) { //맨 밑에 출력문 출력하기 위해 True말고 조건 넣어야함
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int count = (int)(Math.random()*5 + 1) * 1000;
//1~5에 *1000해서 1000~5000까지 랜덤으로 나오도록 함
drink.sale(count);
}
System.out.println(Thread.currentThread().getName() + "끝!");
}
}
}
=>
[당산지점] 주문 4000개 | 현재 재고 46000개
[영등포지점] 주문 4000개 | 현재 재고 42000개
[kh지점] 주문 3000개 | 현재 재고 39000개
[영등포지점] 주문 1000개 | 현재 재고 38000개
[당산지점] 주문 4000개 | 현재 재고 34000개
[kh지점] 주문 3000개 | 현재 재고 31000개
[영등포지점] 주문 3000개 | 현재 재고 28000개
[당산지점] 주문 1000개 | 현재 재고 27000개
[kh지점] 주문 2000개 | 현재 재고 25000개
[당산지점] 주문 5000개 | 현재 재고 20000개
[영등포지점] 주문 1000개 | 현재 재고 19000개
[kh지점] 주문 5000개 | 현재 재고 14000개
[당산지점] 주문 2000개 | 현재 재고 12000개
[영등포지점] 주문 2000개 | 현재 재고 10000개
[kh지점] 주문 3000개 | 현재 재고 7000개
[당산지점] 주문 5000개 | 현재 재고 2000개
재고가 부족합니다.
재고가 부족합니다.
재고가 부족합니다.
재고가 부족합니다.
재고가 부족합니다.
재고가 부족합니다.
[영등포지점] 주문 1000개 | 현재 재고 1000개
[kh지점] 주문 1000개 | 현재 재고 0개
kh지점끝!
재고가 부족합니다.
당산지점끝!
재고가 부족합니다.
영등포지점끝!
https: 가 http: 보다 보안이 더 강화된 Protocol
반응형 웹: 내가 무슨 디바이스를 사용하냐에 따라 볼 수 있는 화면이 다른 것
시멘틱이 들어가서 태그만 보고도 이게 무슨 태그인지 알 수 있게 함
-VS code 설치-
Mouse Wheel Zoom: ctrl과 함께 마우스 휠을 돌리면 확대/축소 가능
encoding = UTF-8로 호환성 설정
기본 브라우저 단축키와 새로운 브라우저 여는 단축키
Ctrl + Q + S를 많이 씀
여는태그, 닫는태그를 자동으로 써주는 것
원하는 내용 드래그나 행 번호 클릭 후 엔터하면 p태그로 묶임
여는 태그를 수정하면 닫는 태그도 자동으로 수정해주는 것
페이지 생성하면 자동으로 새로고침 해줘서 변화를 즉각적으로 볼 수 있음
이미지를 넣으면 행번호에 작게 프리뷰할 수 있는 것
html은 VScode에서 프리뷰 확인하면서 공부해야될듯.
dt는 더 두꺼운 글씨 dd는 일반 글씨