2021-02-25-TIL

A는 B인데 A는 B의 다른 것들과는 어떠한 점이 다르다. 와 같이 설명하는 것이 바람직하다.

A는 A이다. 라는 설명은

쓰레드는 프로그램의 실행(PC와 흐름 일부)을 추상화 한 것 이다. 쓰레드는 무엇이 필요한가? -> PC(어디까지 실행되었는지 알아야한다), 스택(메서드 단위로 실행, 최소단위가 메서드)

Runnable은 매개값이 없고 리턴값이 없는 함수형 인터페이스 이다.

스레드 생성방법

https://m.blog.naver.com/PostView.nhn?blogId=tkddlf4209&logNo=220487061964&proxyReferer=https:%2F%2Fwww.google.com%2F

스레드를 실행하는 방법

main method, new Thread

start() 를 누르면 main에서 t1스레드가 하나 생긴다.

스레드 갯수가 많은 이유

우리가 만들지 않아도 JVM에 GC나 기타 백그라운드 스레드가 존재하므로 스레드 번호가 18번 정도이다.

스레드의 종료 시점

모든 일반 스레드가 끝나야 끝난다. 일반 스레드가 실행중이라면 메인 스레드가 종료되어도 ㅍ프로그램은 계속 실행된다.

데몬스레드도 모든 일반스레드가 종료되어야만 종료된다.

스레스 실행 시간

run()할때는 스레드 생성없이 하므로 순차실행, start()하면 스레드가 생성되지만 main이 먼저 끝나버릴 수 있다. join()을 하면 이 스레스가 끝날때까지 기다린다. 해당 스레드가 끝날때까지 저는 멈춰주세요 라는 뜻이다.

join()은 실제 스레드의 동작과 의미가 있다. 스레드가 하나밖에 없는데 스레드를 추가로 만들면( start() ) 흐름이 갈라지는 느낌이다. 그리고 기다렸다가 종료하는 것은 흐름이 join의 모습과 유사하다.

왜 느려질까?

우리 컴퓨터의 표준출력은 하나이다. 그런데 이를 멀티스레드로 실행하면 오히려 더 느려진다. 차차리 순차적으로 실행하느니만 못하다. 하지만 그냥 단순한 연산은 멀티스레드로 하면 코어갯수에 따라 임계치까지는 무조건 빨라진다.

synchronized

객체에다가 걸 수 있다. 또는 자기자신에게 걸 수 있다. 그러면 프리미티브에는 어떻게 락을 걸 수 있는가? -> 없다. synchronized된 Long같은 것은 없다. 기본적으로 래퍼클래스에는 synchronized키워드가 안 먹힌다.

자물쇠를 열고닫는 오버헤드를 보려면 start와 run을 바꿔서 시간측정을 해보면 된다.

매번 동기화하는것보다 지역변수로 더한다음,

AtomicInteger는 동일한 효과를 낸다.

https://stackoverflow.com/questions/2282166/java-synchronizing-on-primitives

스레드 상태

https://androidtest.tistory.com/51#:~:text=%EC%8A%A4%EB%A0%88%EB%93%9C%20%EC%83%81%ED%83%9C%ED%99%95%EC%9D%B8%EC%9D%80%20%EC%8A%A4%EB%A0%88%EB%93%9C,%EC%88%9C%EC%9C%BC%EB%A1%9C%20%EC%83%81%ED%83%9C%EA%B0%80%20%EB%B3%80%ED%95%9C%EB%8B%A4.

http://blog.naver.com/PostView.nhn?blogId=qbxlvnf11&logNo=220921178603&parentCategoryNo=&categoryNo=12&viewDate=&isShowPopularPosts=true&from=search

Thread.sleep()인 이유

t.sleep()이 아니라 Thread.sleep()인 이유는 그냥 실행중인(run) 스레드가 sleep하는 것이 당연하기 때문이다. 해당 문맥의 스레드가 잠든다.

InterruptedException의 처리

바로 catch해주어야 한다. throws하면 위험하다. InterreptedException은 sleep하는 스레드를 강제로 깨워줄 때, 또는 돌아가고 있을 때 방해하기 위해서 사용한다. 깨울때는 반드시 어떻게 동작할지 정의해 주어야한다. (그냥 throws해서 넘겨주는 것은 바람직하지 x)

그런 느낌도 있는데 자고있는 상태이나 깨어있는 상태 두 상태에서 사용가능해서 t.intterupt() 일것 같기도 해요

isInterrupted 와 interrupted가 있다. 체크하고 바꾸는 것이 있고 안 바꾸는 것이 있다.

https://www.baeldung.com/java-illegalmonitorstateexception

https://www.baeldung.com/java-wait-notify

동시에 흡혈하면 데드락이 걸릴 수 있다. 그럴 떄는 notify등을 사용할 수 있다.

real MYSQL 책

내일 5시 1번방

꿈이나 술을 많이 먹은 상태에서는 분명히 기억상에 존재하는데 깨어나면 모두 사라지는 경험이 있다. 이것이 실제로 메모리 휘발성과 비슷해보인다.

[CODE REVIEW] 미션 4: by woody

  • Board
    • Game 클래스에서 System.out.println(board.showBoard())를 하는데 메서드명이 String을 반환하기만 하고 출력해주는 것이 아니니깐 메서드명의 변경도 고려해볼 수 있는 것 같습니다.
  • Game
    • ongoing보다는 isValid 같은 형태가 좀 더 boolean변수의 이름으로 직관적인 것 같다는 생각이 듭니다.
  • Piece
    • Piece에 equals와 hashCode를 오버라이드한 목적이 궁금합니다. (현재 쓰이는지)
  • Rank
    • throw한 에러 처리는 어떻게 되는건지 궁금합니다.

[roach]

  • initBlackPieces()에서 Rank가 1급 콜렉션인데, 정적 팩토리 메서드를 두는게 어떤지 고려해볼만 하다.
  • Color의 default는 필요없지 않은지?
  • Rank의 find는 검증로직이 하나인데 따로 메서드 분리하는 것이 좋은것 같다. 메서드 내부에서 throw하는 것 보다는 verifty하는 메서드에서 별도로 그 로직을 구현하는 것이 낫다고 한다.
  • Color의 toString이 어디에서 사용되는지 모르겠다.

[hiro]

  • Piece의 equals의 역할이 무엇인지 모르겠다. -> 객체가 싱글톤이 아니라 팩토리 메서드로 계속 생성하므로 equals와 hashCode의 사용이 필요하다.

[프레디]

  • ongoing이 try문 안에 있는게 변수의 사용을 좀 더 지엽적으로 범위를 제한해줄 수 있을 것 같다.
  • value라는 이름이 무엇을 리턴하는 것인지 모호한 것 같다.
  • Rank의 예외처리에서 인자에 대한 예외이 이 경우에는 JVM에서 기본적으로 처리해주는 에러인데 catch로 처리할 것이 아니라면 그냥 작성이 의미가 없을 수 있다. 유의미함만 따지면 Array인덱스 예외보다는 오히려 인자에 관한 예외객체를 사용하는 것이 더 나은 것 같다. 그리고 현재의 코드는 throw가 코드의 흐름을 읽는데 약간의 방해가 될 수도 있는 것 같다.
  • Rank의 forEach는 리턴값없이 밖에 있는 값의 상태를 계속 변경시키는 사이드 이팩트가 있다. 그래서 클래식하게 쓰는게 오히려 나을수도 있다. 스트림을 쓸거라면 stream이나 collectors의 메서드를 사용하는 방법도 있다. *keyword : 스트림으로 문자열 합치기

size()를 call 할때마다 구한다?