class ThreadDemo01 extends Thread{
ThreadDemo01(String name){
super(name);
}
@Override
public void run() {
//thread프로그래밍으로 실행하고싶은 내용을 정의
for(int i=1;i<=20;i++) {
System.out.print(i+"("+getName()+")"+"\t");
try {
Thread.sleep(500);//0.5초 쉬게 하기
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i%5==0) {
System.out.println();
}
}
}
}
public class ThreadTest01 {
public static void main(String[] args) {
System.out.println("*****메인시작********");
ThreadDemo01 t1 = new ThreadDemo01("t1");
ThreadDemo01 t2 = new ThreadDemo01("t2");
// t1.run(); ---쓰레드 작업이 아니라 단순 메소드 call
// t2.run();
t1.start();
t2.start();
System.out.println("*****메인종료********");
}
}


class AlphaThread extends Thread{
@Override
public void run() {//run메소드 오버라이드 해야함
for(char i ='A';i<='Z';i++) {
System.out.print(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class DigitThread extends Thread{
@Override
public void run() {//run메소드 오버라이드 해야함
for(int i=1;i<=100;i++) {
System.out.print(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i%10==0) {
System.out.println();
}
}
}
}
public class ThreadExam01 {
public static void main(String[] args) {
AlphaThread a = new AlphaThread();
DigitThread d = new DigitThread();
a.start();
d.start();
}
}

class RunnableDemo01 implements Runnable{
@Override
public void run() {
for(int i=1;i<=20;i++) {
//getName은 Thread클래스에 정의되어있는 메소드이므로 Runnable에서는 사용할 수 없다
//Thread.currentThread()를 이용해면 현재 실행중인 쓰레드 객체를 리턴받아서 호출
System.out.print(i+"("+Thread.currentThread().getName()+")"+"\t");
try {
Thread.sleep(500);//0.5초 쉬게 하기
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i%5==0) {
System.out.println();
}
}
}
}
public class RunnableTest01 {
public static void main(String[] args) {
System.out.println("*****메인시작********");
//1.러너블 하위객체를 생성
RunnableDemo01 obj = new RunnableDemo01();
//2.생성한 러너블 하위객체를 이용해서 쓰레드 객체를 생성
Thread t1 = new Thread(obj,"t1");
Thread t2 = new Thread(new RunnableDemo01(),"t2");
t1.start();
t2.start();
for(int i=1;i<=10;i++) {
System.out.println("main쓰레드");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("*****메인종료********");
}
}

class AlphaRunnable implements Runnable{
@Override
public void run() {
for(char a ='A';a<='Z';a++) {
System.out.print(a);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class DigitRunnable implements Runnable{
@Override
public void run() {
for(int i=1;i<=100;i++) {
System.out.print(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i%10==0) {
System.out.println();
}
}
}
}
public class RunnableExam01 {
public static void main(String[] args) {
Thread t1 = new Thread(new AlphaRunnable());
Thread t2 = new Thread(new DigitRunnable());
t1.start();
t2.start();
}
}
public class RunnableTest02_Inner {
public static void main(String[] args) {
System.out.println("메인시작");
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=20;i++) {
System.out.print("익명이너클래스");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
System.out.println("메인종료");
}
}

public class BeepPrintExam {
public static void main(String[] args) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for (int i = 1; i <= 5; i++) {
toolkit.beep();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <= 5; i++) {
System.out.println("띵");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class BeepPrintExam_Thread {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for (int i = 1; i <= 5; i++) {
toolkit.beep();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("띵");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
class MyThread extends Thread{
@Override
public void run() {
//시간지연을 위한 코드 - 프로그램이 실행되는 시간을 표현
for (int i = 1; i <= 10000; i++) {
}
System.out.println(getName()+"쓰레드의 우선순위->"+getPriority());
}
}
//지금은 그냥 쓰레드에서 처리하는 일 없이 쓰레드의 우선순위만 출력
public class ThreadPriortyTest {
public static void main(String[] args) {
//숫자가 클수록 우선순위가 높다
System.out.println(Thread.MAX_PRIORITY);
System.out.println(Thread.MIN_PRIORITY);
System.out.println(Thread.NORM_PRIORITY);
//CPU의 성능을 판단하는 기준 중 하나가 코어의 수
//연산을 여러개의 코어가 처리하기 때문에 코어수가 많으면 빠르게 처리할 수 있다.
System.out.println("코어수:"+Runtime.getRuntime().availableProcessors());
for (int i = 1; i <= 3; i++) {
MyThread t = new MyThread();
t.start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//쓰레드의 우선순위를 변경할수있다
for (int i = 1; i <= 10; i++) {
MyThread t = new MyThread();
t.setName("t"+i);
if(i==7) {
t.setPriority(Thread.MAX_PRIORITY);
}
t.start();
}
}
}

public class ThreadMethodTest {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println("쓰레드이름:"+t.getName());
System.out.println("실행중인쓰레드의갯수:"+Thread.activeCount());
//아무일도 하지않는 쓰레드 만들기
for (int i = 0; i <= 3; i++) {
Thread t2 = new Thread("t"+i);
System.out.println(t2.getName());
t2.start();
}
System.out.println("실행중인쓰레드의갯수:"+Thread.activeCount());
//console창에 찍히는 타이밍이 달라서, 이미끝난건 반영안됨
}
}

class MyThread2 extends Thread{
@Override
public void run() {
for(int i=1;i<=10;i++) {
System.out.println(i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class DaemonThreadTest {
public static void main(String[] args) {
System.out.println("*****메인시작********");
MyThread2 t = new MyThread2();
t.setDaemon(true);//데몬쓰레드로 설정한거//false는 안한거랑 같음
//데몬쓰레드로 만드는 작업은 start 되기 전에 작업
t.start();//데몬쓰레드여도 실행자체는 스타트를 써야함.
for(int i=1;i<=10;i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("*****메인종료********");
}
}

한번 start된 스레드는 절대 다시 실행할 수 없다.
->스레드는 일회용
class StopThread extends Thread{
//현재 상태값을 저장할 수 있는 변수
private boolean state = true;
//기본값작업안하면 펄스라서 처리
public void run() {
while(state) {
System.out.println("현재쓰레드의 상태: 실행중~~~");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("현재쓰레드의 상태:종료상태");
}
//스레드의 현재 상태값이 저장된 변수를 변경할 수 있는 메소드
public void stopThread() {
state = false;
}
}
public class StopThreadTest01 {
public static void main(String[] args) {
System.out.println("*****메인시작********");
StopThread t = new StopThread();
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//쓰레드 실행을 제어하는 변수인 쓰레드객체의 state를 변경하면서 쓰레드를 종료
t.stopThread();
System.out.println("*****메인종료********");
}
}

class StopThread02 extends Thread{
public void run() {
//인터럽트가 발생되지 않는동안 실행할 수 있도록 처리
try {
while(!Thread.currentThread().isInterrupted()) {
//와일문은 인터럽트발생되어도 실행되니까 빠져나올수있게 트라이문안으로
System.out.println("현재쓰레드의 상태: 실행중~~~");
Thread.sleep(500);
}
}catch (InterruptedException e) {
}finally {
System.out.println("현재쓰레드의 상태:종료상태");
}
}
}
public class StopThreadTest02 {
public static void main(String[] args) {
System.out.println("*****메인시작********");
StopThread02 t = new StopThread02();
t.start();
System.out.println("쓰레드이름 :"+t.getName());
//인터럽트가 발생되면 true, 그렇지 않으면 false
System.out.println("인터럽트 상태 :"+t.isInterrupted());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//인터럽트를 발생시키는 작업
t.interrupt();
System.out.println("인터럽트상태:"+t.isInterrupted());
System.out.println("인터럽트상태:"+t.isInterrupted());
System.out.println("인터럽트상태:"+t.isInterrupted());
System.out.println("*****메인종료********");
}
}

public class ThreadStateTest {
public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("쓰레드의 상태:"+t.getState());//처음스레드가 만들어졌을때 상태
t.start();
System.out.println("쓰레드의 상태:"+t.getState());
System.out.println("쓰레드의 상태:"+t.getState());
System.out.println("쓰레드의 상태:"+t.getState());//실행될때
System.out.println("쓰레드의 상태:"+t.getState());
System.out.println("쓰레드의 상태:"+t.getState());
System.out.println("쓰레드의 상태:"+t.getState());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("쓰레드의 상태:"+t.getState());//종료된후
}
}

class EvenThread extends Thread{
private boolean state = true;
@Override
public void run() {
int i = 2;
while (state &i<=100) {
System.out.println("값:"+i);
try {
Thread.sleep(100);
}catch (InterruptedException e) {
e.printStackTrace();
}
i = i+2;
if(i>50) {
stopThread();
}
}
}
//쓰레드의 현재 상태값이 저장된 변수를 변경할 수 있는 메소드
public void stopThread() {
state = false;
}
}
class OddThread extends Thread{
@Override
public void run() {
int i = 1;
while(!Thread.currentThread().isInterrupted() & i<=1000) {
System.out.println("값:"+i);
try {
Thread.sleep(200);
}catch (InterruptedException e) {
e.printStackTrace();
}
i = i +2;
if(i>70) {
interrupt();
}
}
}
}
public class ThreadExam02 {
public static void main(String[] args) {
EvenThread t = new EvenThread();
t.start();
OddThread t2 = new OddThread();
t2.start();
}
}



이렇게 할 수도 있다..~
모든 쓰레드가 공유하는 객체(공유자원)
public class Toilet {
//synchronized 빼면 무작위로됨
public synchronized void open(String name) {//name은 공유객체를 사용하ㄴㄴ 쓰레드의 이름
System.out.println(name+"이 문열고 들어옴");
for(int i=1;i<=100000000;i++) {
if(i==10000) {
System.out.println(name+"가 끙~~~~아~~~~");
}
}
System.out.println(name+"이 문열고 나감");
}
}
public class User extends Thread{
String name;
Toilet toilet;
public User(String name, Toilet toilet) {
super();
this.name = name;
this.toilet = toilet;
}
@Override
public void run() {
toilet.open(name);
}
}
//여러쓰레드가 객체를 공유해서 사용하는 경우 발생할 수 있는 문제점
//->synchronized를 Toilet에 줘서 하나씩
public class ThreadSyncTest01 {
public static void main(String[] args) {
//쓰레드에서 공유해서 사용할 객체 생성
Toilet toilet = new Toilet();
//공유객체를 사용하게 될 쓰레드들을 생성
User user1 = new User("장동건",toilet);
User user2 = new User("차은우",toilet);
User user3 = new User("한소희",toilet);
User user4 = new User("김태희",toilet);
User user5 = new User("한지민",toilet);
User user6 = new User("김혜수",toilet);
user1.start();
user2.start();
user3.start();
user4.start();
user5.start();
user6.start();
//들어오고 나가고 속도 다름
}
}

public class ThreadSyncTest02 {
public static void main(String[] args) {
//공유객체를 생성 - 계좌이체 정보를 셋팅할 객체
Obj obj = new Obj();
obj.acc1 = new Account("111-222-333", 10000000,"김서연");
obj.acc2 = new Account("777-888-999", 50000000,"장동건");
AccountTransferThread t1 = new AccountTransferThread(obj);//쓰레드로 만들기
Thread t2 = new Thread(new AccountSumThread(obj));//러너블로 만들기
t1.start();
t2.start();
}
}
전에 만든거 단순히 가져온거
public class Account {
private String accId;
private long balance;
private String ownerName;
public Account() {
}
public Account(String accId, long balance, String ownerName) {
super();
this.accId = accId;
this.balance = balance;
this.ownerName = ownerName;
}
//입금하기
public void deposit(long amount) {
balance = balance + amount;
}
//출금하기
public void withdraw(long amount) {
balance = balance - amount;
}
public String getAccId() {
return accId;
}
public void setAccId(String accId) {
this.accId = accId;
}
public long getBalance() {
return balance;
}
public void setBalance(long balance) {
this.balance = balance;
}
public String getOwnerName() {
return ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
}
public class Obj {
Account acc1;//김서연계좌 - 이체를 받을 계좌
Account acc2;//장동건계좌 - 이체할 계좌
//공유객체에 메소드를 직접정의하고 사용하는 경우
public synchronized void 계좌이체() {
for(int i=1;i<=20;i++) {
acc2.withdraw(1000000);
System.out.println("100만원을 출금했습니다.");
acc1.deposit(1000000);
System.out.println("100만원을 입금했습니다.");
}
}
public synchronized void 출금하기() {
for(int i=1;i<=5;i++) {
long total = acc1.getBalance()+acc2.getBalance();
System.out.println("총잔액=>"+total);
}
}
}
public class AccountTransferThread extends Thread{
Obj obj; //공유객체
public AccountTransferThread(Obj obj) {
super();
this.obj = obj;
}
@Override
public void run() {
//공유객체의 메소드를 호출
obj.계좌이체();
}
}
public class AccountSumThread implements Runnable{
Obj obj; //공유객체
public AccountSumThread(Obj obj) {
super();
this.obj = obj;
}
@Override
public void run() {
//공유객체의 메소드를 호출
obj.출금하기();
}
}

본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.