2018.01.11 멀티 스레드의 활용

2019. 1. 11. 16:22JAVA

<슬롯 머신 : 멀티스레드의 활용>


① MainApp 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.exam.app;
 
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
 
public class MainApp extends Application {
    public static ExecutorService executorServiceor = Executors.newFixedThreadPool(8); //선언
 
    @Override
    public void start(Stage primaryStage) {
        Scene scene = null;
        try {
            Parent root =FXMLLoader.load(getClass().getResource("view/Root.fxml"));
            scene = new Scene(root);
        }catch(IOException e) {
            e.printStackTrace();
        }
        primaryStage.setScene(scene);
        primaryStage.setTitle("슬롯");
        primaryStage.setResizable(false);
        primaryStage.show();
        
        
    }
 
    @Override
    public void stop() throws Exception {
        executorServiceor.shutdown(); // 닫기버튼을 누를 때 프로세스도 함께 종료하게 만듬 
    }
 
    public static void main(String[] args) {
        
        launch(args);
    }
}
 
cs



② RootController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package com.exam.app.view;
 
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
import javax.management.StringValueExp;
 
import com.exam.app.MainApp;
 
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
 
public class RootController implements Initializable {
    @FXML
    private Label lblMessage, label1, label2, label3;
    private int twinkleA = 0;
    private int twinkleB = 0;
    @FXML
    private Button btn; // 필드속성이 다를 경우 @FXML을 따로 지정해줘야한다.
    private ExecutorService executorService = MainApp.executorServiceor; // MainApp.class의  ExecutorService로 연결
    private Future<Integer> future1,future2,future3;
    @FXML
    private AnchorPane container;
 
    @Override
    public void initialize(URL location, ResourceBundle resources) {
 
        // PLAY NOW!! 글자색 반짝이기 작업스레드
        Thread th = new Thread(new Runnable() {
 
            @Override
            public void run() {
                while (true) {
                    if (twinkleA == 0) {
                        lblMessage.setStyle("-fx-text-fill:red");
                        twinkleA = 1;
                    } else {
                        lblMessage.setStyle("-fx-text-fill:blue ");
                        twinkleA = 0;
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
 
                } // while()
            }
        });
        th.setDaemon(true);
        th.start();
 
        // 버튼 동작
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 버튼 비활성화 → 작업이 종료되기 전까지 간섭하지 못하도록 설정
                btn.setDisable(true);
                /*스레드 동시 동작을 위한executorService.submit()*/
                // label1 돌리기
                future1 = executorService.submit(new Callable<Integer>() {// 작업스레드1
 
                    @Override
                    public Integer call() throws Exception {
                            int num = roll(label1,30);
                            return num;
                    }
 
                });
                // label2 돌리기
                future2 = executorService.submit(new Callable<Integer>() { // 작업스레드2
 
                    @Override
                    public Integer call() throws Exception {
                            int num = roll(label2,60);
                            return num;
                    }
 
                });
                // label3 돌리기
                future3 = executorService.submit(new Callable<Integer>() {// 작업스레드 3
 
                    @Override
                    public Integer call() throws Exception {
                            int num = roll(label3,90);
                            return num;
                    }
 
                });
 
                executorService.submit(new Runnable() { // 최종결과값을 스레드화 시켜 동시 실행,작업스레드4
                    
                    @Override
                    public void run() {
                        result();
                        
                    }
                });
            }// handle()
        });// btn()
    }// initialize()
    
    // label숫자가 회전 후 리턴
    int roll(Label label,int count) {
        int result= 0;
        label.setStyle("-fx-text-fill: blue; -fx-background-color: yellow;");
        for (int i = 1; i <=count; i++) {
            int num = (int) (Math.random() * 9)+1;
            Platform.runLater(new Runnable() {// 스레드에선 UI화면을 변경할 수 없으므로 Platform.runLater을 사용
 
                @Override
                public void run() {
                    label.setText(String.valueOf(num));
                }
            });// Platform
            if(i==count) {
                result =num;
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }//for
        label.setStyle("-fx-text-fill: red; -fx-background-color: yellow;");
        return result;
    }//roll()
    
    // 결과 처리 메소드
    void result(){
        int num1=0, num2=0, num3=0;
        try {
            num1=future1.get(); // 블로킹 메소드
            num2=future2.get();
            num3=future3.get();
        } catch (InterruptedException |ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(num1+":"+num2+":"+num3);
        // 값에 따라 배경 화면 변경
        if(num1==num2 && num2==num3) {
            for(int i =0; i<10; i++) {
                if(twinkleB == 0) {
                    container.setStyle(" -fx-background-color: red;");
                    twinkleB=1;
                }else {
                    container.setStyle(" -fx-background-color: yellow;");
                    twinkleB=0;
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }else {
            for(int i =0; i<4; i++) {
                if(twinkleB == 0) {
                    container.setStyle(" -fx-background-color: black;");
                    twinkleB=1;
                }else {
                    container.setStyle(" -fx-background-color: green;");
                    twinkleB=0;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        container.setStyle(" -fx-background-color: white;");
        btn.setDisable(false);
    }//result()
    
 
}// RootController()
 
cs


▼출력화면 ▼