[실행 결과]
내 전체 코드
import java.lang.*;
class Student extends Thread { // 쓰레드 학생 클래스
String name; // 학생 이름
int hakbun; // 학생 학번
int time=System.currentTimeMillis(); //시험 시간
Student(String n,int h,int t){
super(name);
super(hakbun);
super(time);
}
public void run() {
Test.test(int h,String n);
Test.goBackHome(int h,String n);
Test.checkProfessor(int h,String n);
Test.checkTestTime(int h,String n,int h);
}
}
class Test { // 공유자원 클래스
void test(int h,String n){
System.out.println(hakbun+"번"+name+"가 JAVA 시험을 보고있다");
}
void goBackHome(int h,String n){
System.out.println(hakbun+"번"+name+"가 집으로 돌아간다");
}
synchronized void checkProfessor(int h,String n) {
System.out.println("안유정교수가"+hakbun+"번"+name+"의 시험지를 확인하고 접수했다");
}
void checkTestTime(int h,String n,int h){
if(time>700){
time.sleep(1.0);
}
else { System.out.println(hakbun+"번"+name+"가 시험본 시간은"+time.random()); }
}
class TestJavaSync { // main 클래스
public static void main(String[] args){
Student s1 = new Student("김별이",2020081001,time);
Student s2 = new Student("유준서",2018081100,time);
Student s3 = new Student("이지은",2019081077,time);
s1.start();
s2.start();
s3.start();
}
}
수정 코드
class Professor { // 공유자원 교수 클래스
String name;
Professor(String n) { name = n; }
synchronized void check_testpaper(Student s) {
s.end = System.currentTimeMillis();
System.out.println(s.number+"번"+s.name+"가 시험본 시간은"+(s.end-s.begin)+"ms");
if((s.end-s.begin)<=700)
System.out.println(name+"교수가"+s.number+"번"+s.name+"의 시험지를 확인하고 접수했다");
else
System.out.println(s.number+"번"+s.name+"의 시험지는 time over");
}
}
class Student extends Thread {
Professor prof;
String name;
int number;
long begin,end;
Student(Professor p,String n,int no){
prof = p;
name = n;
number = no;
}
public void run() {
begin = System.currentTimeMillis(); // end가 없는 이유는 교수님이 시간 check
testJava(name,number); // n,no라고 매개변수 값을 주면 어떻게 되지?
prof.check_testpaper(this); // 교수 객체가 시험지를 check하는 것이니 prof.check~
goHome(name,number);
}
void testJava(String n,int no){
System.out.println(no+"번"+n+"가 JAVA 시험을 보고있다");
try {
Thread.sleep((int)(Math.random()*1000)); }
catch(InterruptedException e) { }
}
void goHome(String n,int no){
System.out.println(no+"번"+n+"가 집으로 돌아간다");
}
}
public class TestJavaSync2 {
public static void main(String[] args){
Professor p = new Professor("방탄소년단");
Student s1 = new Student(p,"김별이",2020081001);
Student s2 = new Student(p,"이지은",2019081077);
Student s3 = new Student(p,"유준서",2018081100);
s1.start();
s2.start();
s3.start();
}
}
코드 비교
main 클래스 (나)
class TestJavaSync { // main 클래스
public static void main(String[] args){
Student s1 = new Student("김별이",2020081001,time);
Student s2 = new Student("유준서",2018081100,time);
Student s3 = new Student("이지은",2019081077,time);
s1.start();
s2.start();
s3.start();
}
}
main 클래스 (수정)
public class TestJavaSync2 {
public static void main(String[] args){
Professor p = new Professor("방탄소년단");
Student s1 = new Student(p,"김별이",2020081001);
Student s2 = new Student(p,"이지은",2019081077);
Student s3 = new Student(p,"유준서",2018081100);
s1.start();
s2.start();
s3.start();
}
}
Student 쓰레드 클래스 (나)
import java.lang.*;
class Student extends Thread { // 쓰레드 학생 클래스
String name; // 학생 이름
int hakbun; // 학생 학번
int time=System.currentTimeMillis(); //시험 시간
Student(String n,int h,int t){
super(name);
super(hakbun);
super(time);
}
public void run() {
Test.test(int h,String n);
Test.goBackHome(int h,String n);
Test.checkProfessor(int h,String n);
Test.checkTestTime(int h,String n,int h);
}
}
Student 쓰레드 클래스 (수정)
class Student extends Thread {
Professor prof;
String name;
int number;
long begin,end;
Student(Professor p,String n,int no){
prof = p;
name = n;
number = no;
}
public void run() {
begin = System.currentTimeMillis(); // end가 없는 이유는 교수님이 시간 check
testJava(name,number); // n,no라고 매개변수 값을 주면 어떻게 되지?
prof.check_testpaper(this); // 교수 객체가 시험지를 check하는 것이니 prof.check~
goHome(name,number);
}
void testJava(String n,int no){
System.out.println(no+"번"+n+"가 JAVA 시험을 보고있다");
try {
Thread.sleep((int)(Math.random()*1000)); }
catch(InterruptedException e) { }
}
void goHome(String n,int no){
System.out.println(no+"번"+n+"가 집으로 돌아간다");
}
}
Professor 공유자원 클래스 (나)
class Test { // 공유자원 클래스
void test(int h,String n){
System.out.println(hakbun+"번"+name+"가 JAVA 시험을 보고있다");
}
void goBackHome(int h,String n){
System.out.println(hakbun+"번"+name+"가 집으로 돌아간다");
}
synchronized void checkProfessor(int h,String n) {
System.out.println("안유정교수가"+hakbun+"번"+name+"의 시험지를 확인하고 접수했다");
}
void checkTestTime(int h,String n,int h){
if(time>700){
time.sleep(1.0);
}
else { System.out.println(hakbun+"번"+name+"가 시험본 시간은"+time.random()); }
}
Professor 공유자원 클래스 (수정)
class Professor { // 공유자원 교수 클래스
String name;
Professor(String n) { name = n; }
synchronized void check_testpaper(Student s) {
s.end = System.currentTimeMillis();
System.out.println(s.number+"번"+s.name+"가 시험본 시간은"+(s.end-s.begin)+"ms");
if((s.end-s.begin)<=700)
System.out.println(name+"교수가"+s.number+"번"+s.name+"의 시험지를 확인하고 접수했다");
else
System.out.println(s.number+"번"+s.name+"의 시험지는 time over");
}
}
1.나는 왜 공유자원 클래스를 Professor가 아닌 시험으로 생각을 했었을까? 지금 생각해보면 시험은 학생들이 동시에 보고 시험이 끝나는 순서대로 나가는 것인데, 왜 처음에 '시험'을 공유자원으로 생각했는지 의문이다. 교수는 한 사람인데 시험지 체크는 한 학생밖에 하지 못하므로 교수를 공유자원으로 설정해야 한다. (학생들에 대한 공유자원)
2. 공유자원 Professor 클래스 안에서 교수 객체가 해야 할 동기화 메소드만 따로 정의하였다. 나는 모든 메소드를 다 집어넣었다. (syn~ 키워드를 통해 동기화 메소드를 구분하긴 했다)
3. 시험시간이 700ms를 오버하면 교수 객체가 time over라고 출력을 해주므로 여기서 end 시간을 만들어주고, 시간이 700ms 판단하여야 한다.
s.name은 매개변수로 Student 클래스로부터 s로 해서 매개변수로 받아온다. 그래서 Student 클래스 내에 있는 (학생의) name인 것이다. 이런 식으로 접근을 해야 한다.
4. 시험지 제출을 하거나 time over이 되어 시험지 제출을 못하는 것은 교수 객체의 판단이다. 그래서 Student 객체의 s.end-s.begin 으로 해서 시험 시간을 판단한 뒤, if~else문을 활용하여 시간에 따른 시험지 제출 여부를 공유자원인 교수 클래스에서 설정해야 한다.