Write a Hello world shell script in mac os x

1. 在家目錄(/Users/RongSon/)下創”bin”資料夾

cd /Users/RongSon
mkdir bin

2. 進去bin資料夾後,開始寫script囉~
cd bin
vim hello.sh
3. script內容:
#!/bin/bash
# Program:
# This program shows "Hello World!" in your screen.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "Hello World! a n"
exit 0

不懂PATH那一行….
只知道是設定環境變數,但是不知道代表的意思
因為在這個範例中
即使不加PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
還是一樣可以印出Hello world!
試過只有打
echo "Hello World! a n"
也是可以跑的
4. 執行shell script:
sh hello.sh
參考:
1. 鳥哥第十二章-學習shell script:
http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script_1st

More practice for multi-thread in java (join)

1. join:

class test2{
public static void main(String[] args){
System.out.println(“Hello test2”);
bThread thread1 = new bThread();
bThread thread2 = new bThread();
bThread thread3 = new bThread();
bThread thread4 = new bThread();
Thread thread1b = new Thread(thread1);
Thread thread2b = new Thread(thread2);
Thread thread3b = new Thread(thread3);
Thread thread4b = new Thread(thread4);

thread1b.start();
thread2b.start();
thread3b.start();
thread4b.start();
        System.out.println(“Thread count: “+ Thread.activeCount());
        
        try{
            thread1b.join(); //wait for thread1 join main thread
            System.out.println(thread1b +” join ~~~~~~”);
            thread2b.join();
            System.out.println(thread2b +” join ~~~~~~”);
            thread3b.join();
            System.out.println(thread3b +” join ~~~~~~”);
            thread4b.join();
            System.out.println(thread4b +” join ~~~~~~”);
            
        }catch(InterruptedException e){
            System.out.println(“join error”);
        }

System.out.println(“Thread count: “+ Thread.activeCount());
}
}

class bThread implements Runnable{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+ “: “+ i);
        }
}
public bThread(){
System.out.println(“This is bThread!”);
}

}


執行結果:

herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-0: 0
Thread count: 5
Thread-3: 0
Thread-2: 0
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-2: 1
Thread-3: 1
Thread-0: 1
Thread-3: 2
Thread-2: 2
Thread-1: 3
Thread-2: 3
Thread-3: 3
Thread-0: 2
Thread-3: 4
Thread-2: 4
Thread-2: 5
Thread-2: 6
Thread-1: 4
Thread-2: 7
Thread-3: 5
Thread-0: 3
Thread-3: 6
Thread-2: 8
Thread-1: 5
Thread-2: 9
Thread-3: 7
Thread-0: 4
Thread-3: 8
Thread-2: 10
Thread-1: 6
Thread-2: 11
Thread-3: 9
Thread-0: 5
Thread-3: 10
Thread-2: 12
Thread-1: 7
Thread-2: 13
Thread-3: 11
Thread-0: 6
Thread-3: 12
Thread-2: 14
Thread-1: 8
Thread-2: 15
Thread-2: 16
Thread-3: 13
Thread-0: 7
Thread-3: 14
Thread-2: 17
Thread-1: 9
Thread-2: 18
Thread-3: 15
Thread-0: 8
Thread-3: 16
Thread-2: 19
Thread-1: 10
Thread-1: 11
Thread-1: 12
Thread-2: 20
Thread-3: 17
Thread-0: 9
Thread-3: 18
Thread-2: 21
Thread-1: 13
Thread-2: 22
Thread-3: 19
Thread-0: 10
Thread-3: 20
Thread-2: 23
Thread-1: 14
Thread-2: 24
Thread-3: 21
Thread-0: 11
Thread-3: 22
Thread-2: 25
Thread-1: 15
Thread-2: 26
Thread-3: 23
Thread-0: 12
Thread-3: 24
Thread-2: 27
Thread-1: 16
Thread-2: 28
Thread-3: 25
Thread-0: 13
Thread-3: 26
Thread-2: 29
Thread-1: 17
Thread-2: 30
Thread-3: 27
Thread-0: 14
Thread-0: 15
Thread-0: 16
Thread-3: 28
Thread-2: 31
Thread-1: 18
Thread-2: 32
Thread-3: 29
Thread-0: 17
Thread-0: 18
Thread-3: 30
Thread-2: 33
Thread-1: 19
Thread-2: 34
Thread-3: 31
Thread-0: 19
Thread-3: 32
Thread-2: 35
Thread-1: 20
Thread-2: 36
Thread-3: 33
Thread-0: 20
Thread-3: 34
Thread-2: 37
Thread-1: 21
Thread-2: 38
Thread-3: 35
Thread-0: 21
Thread-3: 36
Thread-2: 39
Thread-1: 22
Thread-2: 40
Thread-3: 37
Thread-0: 22
Thread-3: 38
Thread-2: 41
Thread-1: 23
Thread-2: 42
Thread-3: 39
Thread-0: 23
Thread-3: 40
Thread-2: 43
Thread-1: 24
Thread-2: 44
Thread-2: 45
Thread-3: 41
Thread-0: 24
Thread-3: 42
Thread-3: 43
Thread-3: 44
Thread-2: 46
Thread-1: 25
Thread-2: 47
Thread-2: 48
Thread-3: 45
Thread-0: 25
Thread-3: 46
Thread-2: 49
Thread-1: 26
Thread-2: 50
Thread-3: 47
Thread-0: 26
Thread-3: 48
Thread-2: 51
Thread-1: 27
Thread-2: 52
Thread-3: 49
Thread-0: 27
Thread-3: 50
Thread-2: 53
Thread-1: 28
Thread-1: 29
Thread-2: 54
Thread-3: 51
Thread-0: 28
Thread-3: 52
Thread-2: 55
Thread-1: 30
Thread-2: 56
Thread-3: 53
Thread-0: 29
Thread-0: 30
Thread-3: 54
Thread-2: 57
Thread-1: 31
Thread-2: 58
Thread-3: 55
Thread-0: 31
Thread-3: 56
Thread-2: 59
Thread-1: 32
Thread-2: 60
Thread-3: 57
Thread-0: 32
Thread-3: 58
Thread-2: 61
Thread-1: 33
Thread-2: 62
Thread-3: 59
Thread-0: 33
Thread-3: 60
Thread-2: 63
Thread-1: 34
Thread-2: 64
Thread-2: 65
Thread-3: 61
Thread-0: 34
Thread-3: 62
Thread-2: 66
Thread-1: 35
Thread-2: 67
Thread-2: 68
Thread-3: 63
Thread-0: 35
Thread-3: 64
Thread-2: 69
Thread-1: 36
Thread-1: 37
Thread-2: 70
Thread-3: 65
Thread-3: 66
Thread-3: 67
Thread-3: 68
Thread-0: 36
Thread-3: 69
Thread-2: 71
Thread-1: 38
Thread-2: 72
Thread-3: 70
Thread-0: 37
Thread-3: 71
Thread-3: 72
Thread-3: 73
Thread-2: 73
Thread-1: 39
Thread-2: 74
Thread-3: 74
Thread-0: 38
Thread-3: 75
Thread-2: 75
Thread-1: 40
Thread-2: 76
Thread-3: 76
Thread-3: 77
Thread-0: 39
Thread-3: 78
Thread-2: 77
Thread-1: 41
Thread-1: 42
Thread-2: 78
Thread-3: 79
Thread-0: 40
Thread-3: 80
Thread-2: 79
Thread-1: 43
Thread-2: 80
Thread-3: 81
Thread-3: 82
Thread-0: 41
Thread-3: 83
Thread-2: 81
Thread-1: 44
Thread-2: 82
Thread-3: 84
Thread-0: 42
Thread-3: 85
Thread-2: 83
Thread-1: 45
Thread-2: 84
Thread-3: 86
Thread-0: 43
Thread-3: 87
Thread-2: 85
Thread-1: 46
Thread-2: 86
Thread-3: 88
Thread-0: 44
Thread-3: 89
Thread-2: 87
Thread-1: 47
Thread-2: 88
Thread-3: 90
Thread-0: 45
Thread-3: 91
Thread-2: 89
Thread-1: 48
Thread-1: 49
Thread-1: 50
Thread-2: 90
Thread-3: 92
Thread-0: 46
Thread-3: 93
Thread-2: 91
Thread-1: 51
Thread-1: 52
Thread-2: 92
Thread-3: 94
Thread-0: 47
Thread-3: 95
Thread-2: 93
Thread-1: 53
Thread-2: 94
Thread-3: 96
Thread-0: 48
Thread-3: 97
Thread-0: 49
Thread-2: 95
Thread-1: 54
Thread-2: 96
Thread-0: 50
Thread-3: 98
Thread-0: 51
Thread-2: 97
Thread-1: 55
Thread-1: 56
Thread-2: 98
Thread-0: 52
Thread-3: 99
Thread-0: 53
Thread-0: 54
Thread-2: 99
Thread-1: 57
Thread-0: 55
Thread-0: 56
Thread-1: 58
Thread-0: 57
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-0: 60
Thread-0: 61
Thread-1: 60
Thread-0: 62
Thread-0: 63
Thread-0: 64
Thread-1: 61
Thread-1: 62
Thread-0: 65
Thread-0: 66
Thread-0: 67
Thread-1: 63
Thread-0: 68
Thread-1: 64
Thread-0: 69
Thread-0: 70
Thread-1: 65
Thread-1: 66
Thread-0: 71
Thread-1: 67
Thread-0: 72
Thread-0: 73
Thread-1: 68
Thread-0: 74
Thread-1: 69
Thread-0: 75
Thread-1: 70
Thread-1: 71
Thread-0: 76
Thread-1: 72
Thread-0: 77
Thread-0: 78
Thread-0: 79
Thread-1: 73
Thread-0: 80
Thread-1: 74
Thread-1: 75
Thread-1: 76
Thread-0: 81
Thread-1: 77
Thread-0: 82
Thread-0: 83
Thread-1: 78
Thread-0: 84
Thread-1: 79
Thread-0: 85
Thread-0: 86
Thread-1: 80
Thread-0: 87
Thread-1: 81
Thread-1: 82
Thread-0: 88
Thread-0: 89
Thread-1: 83
Thread-0: 90
Thread-1: 84
Thread-1: 85
Thread-0: 91
Thread-1: 86
Thread-0: 92
Thread-1: 87
Thread-1: 88
Thread-0: 93
Thread-1: 89
Thread-1: 90
Thread-1: 91
Thread-0: 94
Thread-0: 95
Thread-1: 92
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-1: 93
Thread-0: 99
Thread-1: 94
Thread-1: 95
Thread[Thread-0,5,] join ~~~~~~
Thread-1: 96
Thread-1: 97
Thread-1: 98
Thread-1: 99
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

———————


herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-0: 0
Thread-0: 1
Thread-1: 0
Thread-1: 1
Thread-2: 0
Thread-0: 2
Thread-2: 1
Thread-2: 2
Thread-1: 2
Thread-1: 3
Thread-3: 0
Thread-2: 3
Thread-0: 3
Thread-2: 4
Thread-3: 1
Thread-1: 4
Thread-3: 2
Thread-2: 5
Thread-0: 4
Thread-2: 6
Thread-3: 3
Thread-1: 5
Thread-3: 4
Thread-2: 7
Thread-0: 5
Thread-2: 8
Thread-3: 5
Thread-1: 6
Thread-3: 6
Thread-2: 9
Thread-0: 6
Thread-2: 10
Thread-3: 7
Thread-1: 7
Thread-3: 8
Thread-2: 11
Thread-0: 7
Thread-2: 12
Thread-3: 9
Thread-1: 8
Thread-3: 10
Thread-2: 13
Thread-0: 8
Thread-2: 14
Thread-3: 11
Thread-1: 9
Thread-3: 12
Thread-2: 15
Thread-0: 9
Thread-2: 16
Thread-3: 13
Thread-1: 10
Thread-3: 14
Thread-2: 17
Thread-2: 18
Thread-0: 10
Thread-2: 19
Thread-2: 20
Thread-3: 15
Thread-1: 11
Thread-3: 16
Thread-2: 21
Thread-0: 11
Thread-2: 22
Thread-2: 23
Thread-2: 24
Thread-2: 25
Thread-3: 17
Thread-3: 18
Thread-3: 19
Thread-3: 20
Thread-3: 21
Thread-3: 22
Thread-1: 12
Thread-3: 23
Thread-2: 26
Thread-0: 12
Thread-2: 27
Thread-3: 24
Thread-1: 13
Thread-3: 25
Thread-2: 28
Thread-0: 13
Thread-2: 29
Thread-3: 26
Thread-1: 14
Thread-3: 27
Thread-2: 30
Thread-0: 14
Thread-2: 31
Thread-3: 28
Thread-1: 15
Thread-3: 29
Thread-3: 30
Thread-2: 32
Thread-0: 15
Thread-2: 33
Thread-3: 31
Thread-1: 16
Thread-3: 32
Thread-2: 34
Thread-0: 16
Thread-2: 35
Thread-3: 33
Thread-1: 17
Thread-3: 34
Thread-2: 36
Thread-0: 17
Thread-0: 18
Thread-2: 37
Thread-3: 35
Thread-1: 18
Thread-3: 36
Thread-2: 38
Thread-0: 19
Thread-2: 39
Thread-2: 40
Thread-3: 37
Thread-1: 19
Thread-3: 38
Thread-3: 39
Thread-2: 41
Thread-0: 20
Thread-2: 42
Thread-3: 40
Thread-1: 20
Thread-3: 41
Thread-3: 42
Thread-2: 43
Thread-0: 21
Thread-2: 44
Thread-3: 43
Thread-1: 21
Thread-3: 44
Thread-2: 45
Thread-0: 22
Thread-2: 46
Thread-3: 45
Thread-1: 22
Thread-3: 46
Thread-2: 47
Thread-0: 23
Thread-2: 48
Thread-3: 47
Thread-3: 48
Thread-1: 23
Thread-1: 24
Thread-3: 49
Thread-2: 49
Thread-0: 24
Thread-2: 50
Thread-3: 50
Thread-1: 25
Thread-3: 51
Thread-2: 51
Thread-0: 25
Thread-2: 52
Thread-3: 52
Thread-1: 26
Thread-3: 53
Thread-2: 53
Thread-0: 26
Thread-2: 54
Thread-3: 54
Thread-1: 27
Thread-3: 55
Thread-2: 55
Thread-0: 27
Thread-2: 56
Thread-3: 56
Thread-1: 28
Thread-3: 57
Thread-2: 57
Thread-0: 28
Thread-0: 29
Thread-2: 58
Thread-3: 58
Thread-1: 29
Thread-3: 59
Thread-3: 60
Thread-2: 59
Thread-0: 30
Thread-2: 60
Thread-2: 61
Thread-3: 61
Thread-1: 30
Thread-1: 31
Thread-3: 62
Thread-3: 63
Thread-2: 62
Thread-0: 31
Thread-0: 32
Thread-2: 63
Thread-3: 64
Thread-1: 32
Thread-3: 65
Thread-2: 64
Thread-0: 33
Thread-2: 65
Thread-2: 66
Thread-3: 66
Thread-1: 33
Thread-1: 34
Thread-3: 67
Thread-2: 67
Thread-0: 34
Thread-2: 68
Thread-3: 68
Thread-3: 69
Thread-1: 35
Thread-1: 36
Thread-3: 70
Thread-2: 69
Thread-0: 35
Thread-2: 70
Thread-3: 71
Thread-1: 37
Thread-3: 72
Thread-2: 71
Thread-0: 36
Thread-2: 72
Thread-3: 73
Thread-1: 38
Thread-3: 74
Thread-3: 75
Thread-2: 73
Thread-0: 37
Thread-2: 74
Thread-3: 76
Thread-1: 39
Thread-3: 77
Thread-2: 75
Thread-0: 38
Thread-0: 39
Thread-2: 76
Thread-3: 78
Thread-3: 79
Thread-1: 40
Thread-3: 80
Thread-3: 81
Thread-2: 77
Thread-0: 40
Thread-2: 78
Thread-3: 82
Thread-1: 41
Thread-1: 42
Thread-1: 43
Thread-3: 83
Thread-2: 79
Thread-0: 41
Thread-2: 80
Thread-3: 84
Thread-1: 44
Thread-3: 85
Thread-2: 81
Thread-0: 42
Thread-2: 82
Thread-3: 86
Thread-1: 45
Thread-3: 87
Thread-2: 83
Thread-0: 43
Thread-2: 84
Thread-3: 88
Thread-1: 46
Thread-3: 89
Thread-2: 85
Thread-0: 44
Thread-0: 45
Thread-2: 86
Thread-3: 90
Thread-1: 47
Thread-3: 91
Thread-2: 87
Thread-0: 46
Thread-2: 88
Thread-3: 92
Thread-1: 48
Thread-3: 93
Thread-2: 89
Thread-0: 47
Thread-2: 90
Thread-3: 94
Thread-1: 49
Thread-3: 95
Thread-2: 91
Thread-0: 48
Thread-0: 49
Thread-2: 92
Thread-3: 96
Thread-1: 50
Thread-1: 51
Thread-3: 97
Thread-2: 93
Thread-0: 50
Thread-2: 94
Thread-3: 98
Thread-1: 52
Thread-3: 99
Thread-2: 95
Thread-0: 51
Thread-2: 96
Thread-1: 53
Thread-2: 97
Thread-0: 52
Thread-2: 98
Thread-1: 54
Thread-2: 99
Thread-0: 53
Thread-1: 55
Thread-1: 56
Thread-0: 54
Thread-0: 55
Thread-1: 57
Thread-0: 56
Thread-0: 57
Thread-1: 58
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-1: 60
Thread-1: 61
Thread-0: 60
Thread-1: 62
Thread-0: 61
Thread-0: 62
Thread-1: 63
Thread-0: 63
Thread-0: 64
Thread-1: 64
Thread-0: 65
Thread-1: 65
Thread-0: 66
Thread-0: 67
Thread-1: 66
Thread-0: 68
Thread-1: 67
Thread-0: 69
Thread-1: 68
Thread-0: 70
Thread-0: 71
Thread-1: 69
Thread-1: 70
Thread-0: 72
Thread-1: 71
Thread-0: 73
Thread-1: 72
Thread-0: 74
Thread-1: 73
Thread-1: 74
Thread-0: 75
Thread-0: 76
Thread-1: 75
Thread-0: 77
Thread-1: 76
Thread-1: 77
Thread-0: 78
Thread-1: 78
Thread-1: 79
Thread-0: 79
Thread-0: 80
Thread-1: 80
Thread-0: 81
Thread-1: 81
Thread-1: 82
Thread-0: 82
Thread-0: 83
Thread-0: 84
Thread-1: 83
Thread-0: 85
Thread-1: 84
Thread-0: 86
Thread-0: 87
Thread-1: 85
Thread-1: 86
Thread-0: 88
Thread-1: 87
Thread-1: 88
Thread-0: 89
Thread-1: 89
Thread-0: 90
Thread-0: 91
Thread-1: 90
Thread-0: 92
Thread-0: 93
Thread-1: 91
Thread-1: 92
Thread-0: 94
Thread-1: 93
Thread-0: 95
Thread-1: 94
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-1: 95
Thread-0: 99
Thread-1: 96
Thread-1: 97
Thread-1: 98
Thread-1: 99
Thread[Thread-0,5,] join ~~~~~~
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

——————-

herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
Thread-1: 5
Thread-0: 0
Thread-2: 0
Thread-0: 1
Thread-1: 6
Thread-3: 0
Thread-3: 1
Thread-1: 7
Thread-0: 2
Thread-2: 1
Thread-0: 3
Thread-0: 4
Thread-1: 8
Thread-3: 2
Thread-3: 3
Thread-1: 9
Thread-1: 10
Thread-0: 5
Thread-2: 2
Thread-2: 3
Thread-0: 6
Thread-0: 7
Thread-1: 11
Thread-3: 4
Thread-1: 12
Thread-0: 8
Thread-2: 4
Thread-0: 9
Thread-1: 13
Thread-3: 5
Thread-1: 14
Thread-0: 10
Thread-2: 5
Thread-2: 6
Thread-0: 11
Thread-1: 15
Thread-3: 6
Thread-1: 16
Thread-0: 12
Thread-2: 7
Thread-2: 8
Thread-0: 13
Thread-0: 14
Thread-1: 17
Thread-1: 18
Thread-3: 7
Thread-1: 19
Thread-1: 20
Thread-0: 15
Thread-0: 16
Thread-0: 17
Thread-0: 18
Thread-0: 19
Thread-0: 20
Thread-0: 21
Thread-0: 22
Thread-0: 23
Thread-0: 24
Thread-0: 25
Thread-0: 26
Thread-0: 27
Thread-2: 9
Thread-0: 28
Thread-0: 29
Thread-0: 30
Thread-0: 31
Thread-1: 21
Thread-1: 22
Thread-3: 8
Thread-1: 23
Thread-1: 24
Thread-0: 32
Thread-0: 33
Thread-0: 34
Thread-2: 10
Thread-0: 35
Thread-0: 36
Thread-0: 37
Thread-2: 11
Thread-2: 12
Thread-2: 13
Thread-2: 14
Thread-2: 15
Thread-2: 16
Thread-2: 17
Thread-2: 18
Thread-2: 19
Thread-2: 20
Thread-1: 25
Thread-1: 26
Thread-1: 27
Thread-1: 28
Thread-1: 29
Thread-1: 30
Thread-1: 31
Thread-1: 32
Thread-1: 33
Thread-1: 34
Thread-1: 35
Thread-1: 36
Thread-1: 37
Thread-1: 38
Thread-1: 39
Thread-1: 40
Thread-1: 41
Thread-3: 9
Thread-3: 10
Thread-3: 11
Thread-3: 12
Thread-1: 42
Thread-2: 21
Thread-0: 38
Thread-2: 22
Thread-1: 43
Thread-3: 13
Thread-1: 44
Thread-1: 45
Thread-1: 46
Thread-2: 23
Thread-0: 39
Thread-0: 40
Thread-0: 41
Thread-0: 42
Thread-0: 43
Thread-0: 44
Thread-0: 45
Thread-2: 24
Thread-1: 47
Thread-1: 48
Thread-3: 14
Thread-1: 49
Thread-2: 25
Thread-0: 46
Thread-2: 26
Thread-1: 50
Thread-3: 15
Thread-1: 51
Thread-2: 27
Thread-0: 47
Thread-2: 28
Thread-1: 52
Thread-1: 53
Thread-3: 16
Thread-1: 54
Thread-2: 29
Thread-0: 48
Thread-2: 30
Thread-1: 55
Thread-3: 17
Thread-1: 56
Thread-2: 31
Thread-0: 49
Thread-2: 32
Thread-1: 57
Thread-1: 58
Thread-3: 18
Thread-3: 19
Thread-1: 59
Thread-2: 33
Thread-0: 50
Thread-2: 34
Thread-1: 60
Thread-3: 20
Thread-1: 61
Thread-2: 35
Thread-0: 51
Thread-2: 36
Thread-1: 62
Thread-3: 21
Thread-1: 63
Thread-2: 37
Thread-0: 52
Thread-2: 38
Thread-1: 64
Thread-3: 22
Thread-1: 65
Thread-2: 39
Thread-0: 53
Thread-2: 40
Thread-1: 66
Thread-3: 23
Thread-1: 67
Thread-2: 41
Thread-2: 42
Thread-0: 54
Thread-2: 43
Thread-2: 44
Thread-1: 68
Thread-3: 24
Thread-1: 69
Thread-2: 45
Thread-0: 55
Thread-2: 46
Thread-1: 70
Thread-3: 25
Thread-3: 26
Thread-1: 71
Thread-2: 47
Thread-0: 56
Thread-2: 48
Thread-1: 72
Thread-3: 27
Thread-1: 73
Thread-2: 49
Thread-0: 57
Thread-2: 50
Thread-1: 74
Thread-3: 28
Thread-1: 75
Thread-2: 51
Thread-0: 58
Thread-2: 52
Thread-1: 76
Thread-3: 29
Thread-1: 77
Thread-2: 53
Thread-0: 59
Thread-2: 54
Thread-1: 78
Thread-3: 30
Thread-1: 79
Thread-2: 55
Thread-0: 60
Thread-2: 56
Thread-1: 80
Thread-3: 31
Thread-1: 81
Thread-2: 57
Thread-0: 61
Thread-2: 58
Thread-1: 82
Thread-1: 83
Thread-3: 32
Thread-1: 84
Thread-2: 59
Thread-2: 60
Thread-0: 62
Thread-2: 61
Thread-1: 85
Thread-3: 33
Thread-1: 86
Thread-2: 62
Thread-0: 63
Thread-2: 63
Thread-1: 87
Thread-3: 34
Thread-1: 88
Thread-2: 64
Thread-0: 64
Thread-2: 65
Thread-1: 89
Thread-3: 35
Thread-1: 90
Thread-2: 66
Thread-0: 65
Thread-2: 67
Thread-1: 91
Thread-3: 36
Thread-1: 92
Thread-2: 68
Thread-0: 66
Thread-2: 69
Thread-1: 93
Thread-3: 37
Thread-1: 94
Thread-2: 70
Thread-0: 67
Thread-2: 71
Thread-1: 95
Thread-3: 38
Thread-1: 96
Thread-2: 72
Thread-0: 68
Thread-2: 73
Thread-1: 97
Thread-3: 39
Thread-1: 98
Thread-2: 74
Thread-0: 69
Thread-2: 75
Thread-1: 99
Thread-3: 40
Thread-2: 76
Thread-2: 77
Thread-0: 70
Thread-2: 78
Thread-3: 41
Thread-2: 79
Thread-0: 71
Thread-2: 80
Thread-3: 42
Thread-2: 81
Thread-0: 72
Thread-2: 82
Thread-3: 43
Thread-2: 83
Thread-0: 73
Thread-2: 84
Thread-3: 44
Thread-2: 85
Thread-2: 86
Thread-2: 87
Thread-0: 74
Thread-2: 88
Thread-3: 45
Thread-3: 46
Thread-3: 47
Thread-2: 89
Thread-0: 75
Thread-2: 90
Thread-2: 91
Thread-2: 92
Thread-3: 48
Thread-2: 93
Thread-0: 76
Thread-0: 77
Thread-0: 78
Thread-2: 94
Thread-3: 49
Thread-2: 95
Thread-0: 79
Thread-0: 80
Thread-2: 96
Thread-2: 97
Thread-3: 50
Thread-2: 98
Thread-2: 99
Thread-0: 81
Thread-3: 51
Thread-0: 82
Thread-3: 52
Thread-0: 83
Thread-0: 84
Thread-0: 85
Thread-3: 53
Thread-0: 86
Thread-3: 54
Thread-0: 87
Thread-0: 88
Thread-0: 89
Thread-3: 55
Thread-0: 90
Thread-0: 91
Thread-3: 56
Thread-3: 57
Thread-0: 92
Thread-0: 93
Thread-3: 58
Thread-3: 59
Thread-3: 60
Thread-3: 61
Thread-3: 62
Thread-3: 63
Thread-3: 64
Thread-3: 65
Thread-3: 66
Thread-3: 67
Thread-3: 68
Thread-0: 94
Thread-3: 69
Thread-0: 95
Thread-0: 96
Thread-3: 70
Thread-0: 97
Thread-3: 71
Thread-0: 98
Thread-0: 99
Thread-3: 72
Thread-3: 73
Thread-3: 74
Thread-3: 75
Thread[Thread-0,5,] join ~~~~~~
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread-3: 76
Thread-3: 77
Thread-3: 78
Thread-3: 79
Thread-3: 80
Thread-3: 81
Thread-3: 82
Thread-3: 83
Thread-3: 84
Thread-3: 85
Thread-3: 86
Thread-3: 87
Thread-3: 88
Thread-3: 89
Thread-3: 90
Thread-3: 91
Thread-3: 92
Thread-3: 93
Thread-3: 94
Thread-3: 95
Thread-3: 96
Thread-3: 97
Thread-3: 98
Thread-3: 99
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

結論:
依照main裡面thread的join順序,會有所不同
在main裡join的安排順序是thread1, thread2, thread3, thread4
main執行到thread1b.join();時,會一直等到thread1執行結束後,main才會繼續往下跑
thread1結束後,就依此類推到thread2,3,4
所以即使thread2,3,4比thread1先執行完了,也是要先等thread1執行完且也join了
才輪得到2,3,4來join
參考:
1. 執行緒的加入(join):http://openhome.cc/Gossip/JavaGossip-V2/JoinThread.htm

How to create multiThread in java

public class Thread extends Object implements Runnable

有兩種方法,繼承Thread or 實作Runnable

1.  繼承Thread:

class test1{
public static void main(String[] args){
System.out.println(“Hello”);
aThread thread1 = new aThread();
aThread thread2 = new aThread();

thread1.setName(“thread1”);
thread2.setName(“thread2”);
thread1.start();
thread2.start();
System.out.println(Thread.activeCount());
}
}


class aThread extends Thread{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName + “: “ + i);
}
}

}

執行結果:
herongsendeMacBook-Air:160704-multithread RongSonHo$ time java test1
Hello
3
thread2: 0
thread1: 0
thread1: 1
thread2: 1
thread1: 2
thread1: 3
thread2: 2
thread2: 3
thread1: 4
thread2: 4
thread1: 5
thread1: 6
thread1: 7
thread1: 8
thread2: 5
thread1: 9
thread2: 6
thread1: 10
thread2: 7
thread1: 11
thread2: 8
thread1: 12
thread2: 9
thread1: 13
thread2: 10
thread1: 14
thread2: 11
thread1: 15
thread2: 12
thread1: 16
thread2: 13
thread1: 17
thread2: 14
thread1: 18
thread2: 15
thread1: 19
thread2: 16
thread1: 20
thread2: 17
thread1: 21
thread2: 18
thread1: 22
thread2: 19
thread1: 23
thread2: 20
thread1: 24
thread2: 21
thread1: 25
thread2: 22
thread1: 26
thread2: 23
thread1: 27
thread2: 24
thread2: 25
thread1: 28
thread2: 26
thread1: 29
thread2: 27
thread1: 30
thread2: 28
thread1: 31
thread2: 29
thread1: 32
thread1: 33
thread1: 34
thread2: 30
thread1: 35
thread1: 36
thread2: 31
thread2: 32
thread1: 37
thread2: 33
thread1: 38
thread1: 39
thread2: 34
thread1: 40
thread2: 35
thread1: 41
thread2: 36
thread1: 42
thread2: 37
thread1: 43
thread2: 38
thread1: 44
thread2: 39
thread1: 45
thread2: 40
thread1: 46
thread2: 41
thread1: 47
thread2: 42
thread1: 48
thread2: 43
thread1: 49
thread2: 44
thread1: 50
thread2: 45
thread1: 51
thread2: 46
thread1: 52
thread2: 47
thread1: 53
thread2: 48
thread1: 54
thread2: 49
thread1: 55
thread2: 50
thread1: 56
thread2: 51
thread1: 57
thread2: 52
thread1: 58
thread2: 53
thread1: 59
thread1: 60
thread2: 54
thread1: 61
thread2: 55
thread1: 62
thread2: 56
thread1: 63
thread2: 57
thread1: 64
thread2: 58
thread1: 65
thread2: 59
thread2: 60
thread1: 66
thread1: 67
thread2: 61
thread1: 68
thread2: 62
thread1: 69
thread2: 63
thread1: 70
thread2: 64
thread1: 71
thread2: 65
thread1: 72
thread2: 66
thread1: 73
thread2: 67
thread1: 74
thread2: 68
thread1: 75
thread2: 69
thread1: 76
thread2: 70
thread1: 77
thread2: 71
thread1: 78
thread2: 72
thread1: 79
thread2: 73
thread1: 80
thread2: 74
thread1: 81
thread2: 75
thread1: 82
thread1: 83
thread2: 76
thread1: 84
thread2: 77
thread1: 85
thread2: 78
thread2: 79
thread1: 86
thread2: 80
thread1: 87
thread2: 81
thread1: 88
thread2: 82
thread1: 89
thread2: 83
thread1: 90
thread1: 91
thread2: 84
thread2: 85
thread1: 92
thread2: 86
thread2: 87
thread1: 93
thread2: 88
thread1: 94
thread2: 89
thread2: 90
thread1: 95
thread2: 91
thread2: 92
thread1: 96
thread2: 93
thread1: 97
thread2: 94
thread1: 98
thread2: 95
thread1: 99
thread2: 96
thread2: 97
thread2: 98
thread2: 99

real 0m0.647s
user 0m0.164s
sys 0m0.153s

2. 實作Runnable

class test2{
public static void main(String[] args){
System.out.println(“Hello test2”);
bThread thread1 = new bThread();
bThread thread2 = new bThread();
bThread thread3 = new bThread();
bThread thread4 = new bThread();
Thread thread1b = new Thread(thread1, “thread1”);
Thread thread2b = new Thread(thread2, “thread2”);
Thread thread3b = new Thread(thread3, “thread3”);
Thread thread4b = new Thread(thread4, “thread4”);

thread1b.start();
thread2b.start();
thread3b.start();
thread4b.start();
System.out.println(“Thread count: “+ Thread.activeCount());
}
}

class bThread implements Runnable{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+ “: “+ i);
}
}
public bThread(){
System.out.println(“This is bThread!”);
}

}

執行結果:
herongsendeMacBook-Air:160704-multithread RongSonHo$ time java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-1: 0
Thread count: 5
Thread-3: 0
Thread-2: 0
Thread-0: 0
Thread-2: 1
Thread-3: 1
Thread-1: 1
Thread-3: 2
Thread-2: 2
Thread-0: 1
Thread-2: 3
Thread-3: 3
Thread-1: 2
Thread-3: 4
Thread-2: 4
Thread-0: 2
Thread-2: 5
Thread-3: 5
Thread-1: 3
Thread-3: 6
Thread-2: 6
Thread-2: 7
Thread-0: 3
Thread-2: 8
Thread-3: 7
Thread-1: 4
Thread-3: 8
Thread-2: 9
Thread-0: 4
Thread-2: 10
Thread-3: 9
Thread-1: 5
Thread-3: 10
Thread-2: 11
Thread-0: 5
Thread-2: 12
Thread-3: 11
Thread-1: 6
Thread-3: 12
Thread-2: 13
Thread-0: 6
Thread-2: 14
Thread-2: 15
Thread-3: 13
Thread-1: 7
Thread-3: 14
Thread-2: 16
Thread-0: 7
Thread-2: 17
Thread-3: 15
Thread-1: 8
Thread-3: 16
Thread-2: 18
Thread-0: 8
Thread-2: 19
Thread-3: 17
Thread-1: 9
Thread-3: 18
Thread-2: 20
Thread-0: 9
Thread-2: 21
Thread-3: 19
Thread-1: 10
Thread-3: 20
Thread-2: 22
Thread-0: 10
Thread-2: 23
Thread-3: 21
Thread-1: 11
Thread-3: 22
Thread-2: 24
Thread-0: 11
Thread-2: 25
Thread-3: 23
Thread-1: 12
Thread-3: 24
Thread-2: 26
Thread-0: 12
Thread-2: 27
Thread-3: 25
Thread-1: 13
Thread-3: 26
Thread-2: 28
Thread-0: 13
Thread-2: 29
Thread-3: 27
Thread-1: 14
Thread-3: 28
Thread-2: 30
Thread-0: 14
Thread-2: 31
Thread-3: 29
Thread-1: 15
Thread-3: 30
Thread-2: 32
Thread-0: 15
Thread-2: 33
Thread-3: 31
Thread-1: 16
Thread-3: 32
Thread-3: 33
Thread-3: 34
Thread-2: 34
Thread-0: 16
Thread-0: 17
Thread-2: 35
Thread-3: 35
Thread-1: 17
Thread-3: 36
Thread-2: 36
Thread-0: 18
Thread-2: 37
Thread-3: 37
Thread-3: 38
Thread-3: 39
Thread-1: 18
Thread-3: 40
Thread-2: 38
Thread-0: 19
Thread-2: 39
Thread-3: 41
Thread-1: 19
Thread-3: 42
Thread-2: 40
Thread-2: 41
Thread-0: 20
Thread-0: 21
Thread-2: 42
Thread-3: 43
Thread-1: 20
Thread-3: 44
Thread-2: 43
Thread-0: 22
Thread-2: 44
Thread-3: 45
Thread-1: 21
Thread-3: 46
Thread-2: 45
Thread-0: 23
Thread-2: 46
Thread-3: 47
Thread-1: 22
Thread-3: 48
Thread-2: 47
Thread-0: 24
Thread-2: 48
Thread-3: 49
Thread-1: 23
Thread-3: 50
Thread-2: 49
Thread-0: 25
Thread-2: 50
Thread-3: 51
Thread-1: 24
Thread-3: 52
Thread-2: 51
Thread-0: 26
Thread-2: 52
Thread-3: 53
Thread-1: 25
Thread-3: 54
Thread-2: 53
Thread-0: 27
Thread-2: 54
Thread-3: 55
Thread-1: 26
Thread-3: 56
Thread-2: 55
Thread-0: 28
Thread-2: 56
Thread-3: 57
Thread-3: 58
Thread-1: 27
Thread-3: 59
Thread-2: 57
Thread-0: 29
Thread-2: 58
Thread-3: 60
Thread-1: 28
Thread-3: 61
Thread-2: 59
Thread-0: 30
Thread-0: 31
Thread-2: 60
Thread-3: 62
Thread-1: 29
Thread-3: 63
Thread-2: 61
Thread-2: 62
Thread-0: 32
Thread-0: 33
Thread-2: 63
Thread-2: 64
Thread-3: 64
Thread-1: 30
Thread-3: 65
Thread-2: 65
Thread-0: 34
Thread-2: 66
Thread-3: 66
Thread-1: 31
Thread-3: 67
Thread-2: 67
Thread-2: 68
Thread-0: 35
Thread-2: 69
Thread-3: 68
Thread-1: 32
Thread-1: 33
Thread-1: 34
Thread-3: 69
Thread-2: 70
Thread-0: 36
Thread-2: 71
Thread-3: 70
Thread-3: 71
Thread-1: 35
Thread-3: 72
Thread-2: 72
Thread-0: 37
Thread-2: 73
Thread-3: 73
Thread-1: 36
Thread-3: 74
Thread-2: 74
Thread-2: 75
Thread-0: 38
Thread-2: 76
Thread-3: 75
Thread-1: 37
Thread-3: 76
Thread-2: 77
Thread-0: 39
Thread-2: 78
Thread-3: 77
Thread-1: 38
Thread-3: 78
Thread-2: 79
Thread-0: 40
Thread-2: 80
Thread-3: 79
Thread-1: 39
Thread-3: 80
Thread-3: 81
Thread-3: 82
Thread-2: 81
Thread-0: 41
Thread-2: 82
Thread-3: 83
Thread-1: 40
Thread-3: 84
Thread-2: 83
Thread-0: 42
Thread-2: 84
Thread-3: 85
Thread-1: 41
Thread-3: 86
Thread-2: 85
Thread-0: 43
Thread-2: 86
Thread-3: 87
Thread-1: 42
Thread-1: 43
Thread-3: 88
Thread-2: 87
Thread-0: 44
Thread-2: 88
Thread-3: 89
Thread-1: 44
Thread-3: 90
Thread-2: 89
Thread-0: 45
Thread-2: 90
Thread-3: 91
Thread-3: 92
Thread-1: 45
Thread-3: 93
Thread-2: 91
Thread-0: 46
Thread-2: 92
Thread-3: 94
Thread-1: 46
Thread-3: 95
Thread-2: 93
Thread-0: 47
Thread-2: 94
Thread-3: 96
Thread-1: 47
Thread-3: 97
Thread-2: 95
Thread-0: 48
Thread-2: 96
Thread-3: 98
Thread-1: 48
Thread-3: 99
Thread-2: 97
Thread-0: 49
Thread-2: 98
Thread-2: 99
Thread-1: 49
Thread-0: 50
Thread-1: 50
Thread-1: 51
Thread-0: 51
Thread-1: 52
Thread-0: 52
Thread-1: 53
Thread-0: 53
Thread-1: 54
Thread-0: 54
Thread-1: 55
Thread-0: 55
Thread-1: 56
Thread-0: 56
Thread-1: 57
Thread-0: 57
Thread-1: 58
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-1: 60
Thread-0: 60
Thread-1: 61
Thread-0: 61
Thread-1: 62
Thread-0: 62
Thread-0: 63
Thread-1: 63
Thread-0: 64
Thread-1: 64
Thread-0: 65
Thread-0: 66
Thread-1: 65
Thread-0: 67
Thread-1: 66
Thread-0: 68
Thread-1: 67
Thread-0: 69
Thread-1: 68
Thread-0: 70
Thread-1: 69
Thread-1: 70
Thread-1: 71
Thread-1: 72
Thread-0: 71
Thread-1: 73
Thread-0: 72
Thread-1: 74
Thread-0: 73
Thread-1: 75
Thread-0: 74
Thread-1: 76
Thread-1: 77
Thread-0: 75
Thread-1: 78
Thread-0: 76
Thread-1: 79
Thread-0: 77
Thread-1: 80
Thread-1: 81
Thread-0: 78
Thread-1: 82
Thread-0: 79
Thread-0: 80
Thread-0: 81
Thread-1: 83
Thread-0: 82
Thread-1: 84
Thread-1: 85
Thread-0: 83
Thread-0: 84
Thread-1: 86
Thread-0: 85
Thread-0: 86
Thread-1: 87
Thread-0: 87
Thread-1: 88
Thread-0: 88
Thread-0: 89
Thread-1: 89
Thread-0: 90
Thread-1: 90
Thread-0: 91
Thread-1: 91
Thread-0: 92
Thread-1: 92
Thread-0: 93
Thread-1: 93
Thread-1: 94
Thread-0: 94
Thread-1: 95
Thread-1: 96
Thread-1: 97
Thread-0: 95
Thread-1: 98
Thread-1: 99
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-0: 99

real 0m0.457s
user 0m0.179s
sys 0m0.105s

ps. 預設的Thread Name: Thread-0…

Thread的Constructor:
1. Thread() 分派新的執行緒  -> test1.java
2. Thread(String name)3. Thread(Runnable target) 傳入一個Runnable物件,並分派新的執行緒 -> test2.java
4. Thread(Runnable target, String name) 

常用方法:
1. String getName() 取得名稱
2. int getPriority() 取得優先權
3. void setPriority() 可設參數1~10或MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10
4. void start 將執行丟入Runnable pool中,等待系統run()呼叫
5. void run() 開始執行工作(由系統自動呼叫,非程式設計師撰寫)
6. static void yield() 將目前執行緒先行暫停,重新排程,讓與其他執行緒執行
7. static void sleep(long millis) 暫停目前執行緒,需在try-catch中呼叫,會丟出throws InterruptedException
8. void join() / void join(long millis) 用於調整執行緒執行順序,先暫停目前執行緒,而指定其他執行緒加入執行工作,執行完畢後才回復,或可設定執行時間,需在try-catch中呼叫,會丟出throws InterruptedException
9. void stop() 停止正在執行的執行緒 (不建議使用,易造成死結)
10. void suspend() 停止正在執行的執行緒 (不建議使用,易造成死結)
11. void destroy() 毀掉執行緒
12. boolean isAlive() 取得目前執行緒狀態
13. void wait() 讓執行緒進入等待狀態
14. void notify() 喚醒一個等待中的執行緒,若有多個執行緒,則由JVM決定
15. void notifyAll() 喚醒所有等待中的執行緒





參考:
1. MEMO 123: JAVA筆記-Thread 多執行緒基本撰寫範例與常用函式 :http://jhengjyun.blogspot.tw/2011/04/1.html

How to create multithread in C

#include <stdio.h>#include <pthread.h>#include <stdlib.h>static int count=0;void thread(void){ int i; count++; for(i=0; i<3; i++){ printf(“This is %d pthreadn”, count); }}int main(int argc, char* argv[]){ printf(“Hello worldn”); pthread_t id; int i, ret; ret = pthread_create(&id, NULL, (void *) thread, NULL); if(ret!=0){ printf(“Create pthread error!n”); exit(1); } for(i=0; i<20 ; i++){ printf(“This is main process~~n”); } pthread_join(id, NULL); return 0;}

補充:
1. create new thread:
extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg));
pthread_create的參數裡分成四個部分,
第一個參數把宣告好的pthread丟進去,
第二個參數是更改原本pthread的預設屬性(pthread_attr),
第三個參數是thread要做的事,
第四個參數是thread要做的事所吃的參數
2. waiting process:
extern int pthread_join __P ((pthread_t __th, void **__thread_return));
第一個參數是main process要等待的thread,
第二個參數是thread的return值,把資源給回收回來
也可以使用pthread_exit()
3. 如何修改pthread的預設屬性? (pthread_attr)
#include <pthread.h>
pthread_attr_t attr;
pthread_t tid;

/*初始化属性值,均设为默认值*/
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

pthread_create(&tid, &attr, (void *) my_function, NULL);

4. 如何更改thread的priority? (sched_param)
#include <pthread.h>
#include <sched.h>
pthread_attr_t attr;
pthread_t tid;
sched_param param;
int newprio=20;

pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr, &param);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, &param);
pthread_create(&tid, &attr, (void *)myfunction, myarg);
5. More:(看參考中的網址)
1) Mutual exclusive
2) Semaphore
參考:
1. Linux Multi-Thread programming:
https://sites.google.com/site/myembededlife/Home/applications–development/linux-multi-thread-programming

How to pack a Java program into an executable App in MacOS

要在MacOS內變成執行檔,首先要將Java files編譯成.class,再將所有class檔以command方式包裝成jar檔,再以某種固定的路徑包裝成.app的資料夾=> 就會自己變成app檔

1. 將java files編譯成class files
=> javac test.java

2. 把所有.class檔包進.jar檔
=> 1) 寫manifest.mf檔:內容

Main-Class: test

(需要後面空兩行)

=> 2) 以指令方式包成.jar檔
jar cvfm testApp.jar manifest.mf test.class

3. 測試jar可否執行
=> java -jar testApp.jar

(以上如果是有package的話,請參考http://it-easy.tw/java-jar/)

4. 開啟”Automator” => Choose “Application” => Search “AppleScript”
=> Drag “Run AppleScript” to right side

=>
on run {input, parameters}
set p to POSIX path of (path to me)
do shell script “java -jar ” & p & “/Contents/Java/TestApp.jar”
return input

end run

5. 將已做好的.icns檔替換到/Contents/Resources/AutomatorApplet.icns(檔名也要改)

完成圖:

6. AWTtest.java:
import java.awt.*;import java.awt.event.*;
class Attest{ 
public static void main(String[] args) {
        Frame frame = new Frame(“AWTDemo”);
        frame.addWindowListener(new AdapterDemo());
        frame.setLayout(new FlowLayout());
        Button button = new Button(“AWT1”);
        Checkbox checkbox = new Checkbox(“AWT2”);
        Choice choice = new Choice();
        choice.add(“AWT3”);
        Label label = new Label(“AWT4”);
        List list = new List();
        list.add(“AWT5”); 
        TextArea textarea = new TextArea(“AWT6”);
        TextField textfield = new TextField(“AWT7”);
        frame.add(button);
        frame.add(checkbox); 
        frame.add(choice);
        frame.add(label);
        frame.add(list);
        frame.add(textarea);
        frame.add(textfield);
                 frame.pack();
        frame.setVisible(true);
    }
}
class AdapterDemo extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
}

參考:
1.
[Java]如何將編譯好的.class檔案打包成JAR?:http://it-easy.tw/java-jar/

2. 

Mac 下開發 Java 程式二三事:http://blog.ericsk.org/archives/317
3.

How to convert .jar to .app on Mac – a Java tutorial:https://www.youtube.com/watch?v=kwdK6Dg1a_Y

PhotoUploader: Using Android socket client send photo to Java socket server

大四下最後一學期 Bo的Java期末project
原本就很想做的socket練習
剛好在這次有機會來實做

project內容:
在Android端從圖片庫裡面選一張圖片(可從圖片庫或相簿裡選擇)
透過socket傳給已經在電腦上開好的Java Server

緣由:
因為每次拍完照要傳照片到電腦收藏都很麻煩
不是透過USB線就是透過雲端或是社群軟體或網站
用USB有時候會讀不到或是還要找線很麻煩
而雲端的容量會不夠放、也不確定安不安全
社群軟體或網站(Line, FB)都會把照片壓縮,畫質變很差,而且要一張一張抓
所以不如自己做一個傳照片的App吧!

Demo圖:



會傳到桌面,命名為socketReceive.jpg
使傳照片變得非常方便的App~~~~

Java Server:

JavaSocketServer.java:

import java.io.FileOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class JavaSocketServer implements Runnable {
    
    public static final int SERVERPORT = 5987;
    
    // 最後要儲存照片的位置
    public static final String file_name = “/Users/RongSonHo/Desktop/socketReceive.jpg”;
    public void run() {
        
        try {
            
            System.out.println(“Server: Connecting…”);
            ServerSocket serverSocket = new ServerSocket(SERVERPORT);
            
            while (true) {
                
                Socket client = serverSocket.accept();
                System.out.println(“Server: Receiving…”);
                
                OutputStream out = new FileOutputStream(file_name);
                byte buf[] = new byte[1024];
                int len;
                
                // 讀入從手機端傳來的照片
                InputStream inputStream = client.getInputStream();
                try {
                    while ((len = inputStream.read(buf)) != -1) {
                        // 將照片寫入到電腦裡
                        out.write(buf, 0, len);
                    }
                    out.close();
                    inputStream.close();
                    
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    
                    client.close();
                    System.out.println(“Server: Done.”);
                    
                }
                
            }
            
        } catch (Exception e) {
            
            System.out.println(“Server: Error”);
            e.printStackTrace();
            
        }
        
    }
    public static void main(String str[]) {
        
        Thread desktopSerThread = new Thread(new JavaSocketServer());
        desktopSerThread.start();
        
    }

}



Android Client:

1. activity_main.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    xmlns:tools=”http://schemas.android.com/tools”
    android:layout_width=”match_parent”
    android:layout_height=”match_parent”
    android:paddingBottom=”@dimen/activity_vertical_margin”
    android:paddingLeft=”@dimen/activity_horizontal_margin”
    android:paddingRight=”@dimen/activity_horizontal_margin”
    android:paddingTop=”@dimen/activity_vertical_margin”
    tools:context=”com.javacourse.rongsonho.androidsocketclient.MainActivity”
    android:background=”#006699″>
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:text=”Choose Image”
        android:id=”@+id/button”
        android:background=”#0080FF”
        android:textColor=”@android:color/white”
        android:layout_above=”@+id/button2″
        android:layout_centerHorizontal=”true” />
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:text=”Upload”
        android:id=”@+id/button2″
        android:background=”#0080FF”
        android:textColor=”@android:color/white”
        android:layout_alignParentBottom=”true”
        android:layout_centerHorizontal=”true” />
    <TextView
            android:layout_width=”wrap_content”
            android:layout_height=”wrap_content”
            android:textSize=”25dp”
            android:id= “@+id/textView”
            android:text=”Status”
            android:textColor=”@android:color/white”
            android:scrollbars=”vertical”
            android:singleLine=”false”
            android:maxLines=”20″
            android:layout_alignParentTop=”true”
            android:layout_centerHorizontal=”true” />
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:id=”@+id/refreshLog”
        android:text=”Refresh Log”
        android:layout_alignParentBottom=”true”
        android:layout_alignParentEnd=”true”
        android:background=”#0080FF”
        android:textColor=”@android:color/white”/>
</RelativeLayout>


2. MainActivity.java:

package com.javacourse.rongsonho.androidsocketclient;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
    Socket socket;
    //從手機裡的”我的檔案”選張照片,準備傳到電腦,
    //因不同的手機路徑可能不同,可自行修改。
    //public static final String file_name = “//storage/MicroSD/DCIM/Hello.jpg”;
    Button imageChooser, connecter, refreshLog;
    OutputStream outputstream;
    String ImagePath=””, timeString=””;
    BufferedInputStream bis;
    FileInputStream fis;
    TextView statusText;
    static byte[] mybytearray;
    int serverPort;
    InetAddress serverAddr;
    MyDBHandler dbHandler;
    SimpleDateFormat formatter;
    Date curDate;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageChooser = (Button)findViewById(R.id.button);
        connecter = (Button) findViewById(R.id.button2);
        refreshLog = (Button) findViewById(R.id.refreshLog);
        statusText = (TextView) findViewById(R.id.textView);
        statusText.setMovementMethod(ScrollingMovementMethod.getInstance());
        formatter = new SimpleDateFormat(“yyyy年MM月dd日HH:mm:ss”);
        Date curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
        String timeString = formatter.format(curDate);
        dbHandler = new MyDBHandler(this, null, null, 1);
        dbHandler.addLog(“[*]”+ timeString +”: Choose a picture to send to PCn”);
        printDatabase();
        imageChooser.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                // 建立 “選擇檔案 Action” 的 Intent
                Intent intent = new Intent(Intent.ACTION_PICK);
                // 過濾檔案格式
                intent.setType(“image/*”);
                // 建立 “檔案選擇器” 的 Intent  (第二個參數: 選擇器的標題)
                Intent destIntent = Intent.createChooser(intent, “選擇檔案”);
                // 切換到檔案選擇器 (它的處理結果, 會觸發 onActivityResult 事件)
                startActivityForResult(destIntent, 0);
            }
        });
        connecter.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Thread test = new Thread(clientSocket);
                test.start();
                //statusText.setText(statusText.getText() + “[*] Connecting to server: ” + serverAddr.toString() + “/” + serverPort + ” …n”);
                //statusText.setText(statusText.getText()+”[*] Done!”);
            }
        });
        refreshLog.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                printDatabase();
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        // 有選擇檔案
        if ( resultCode == RESULT_OK ) {
            // 取得檔案的 Uri
            if (data != null) {
                Log.e(“Socket”, “great, data is not null”);
                Uri uri = data.getData();
                if (uri != null) {
                    String path = MagicFileChooser.getAbsolutePathFromUri(this,uri);
                    ImagePath = “/”+ path;
                    Log.e(“Socket”, ImagePath);
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    dbHandler.addLog(“[*]”+timeString+”: “+ “ImagePath: “+ ImagePath + ” n”);
                    File myFile = new File(ImagePath);
                    if (myFile.exists()) {
                        try {
                            mybytearray = new byte[(int) myFile.length()];
                            fis = new FileInputStream(myFile);
                            bis = new BufferedInputStream(fis, 8 * 1024);
                            bis.read(mybytearray, 0, mybytearray.length);
                            Log.e(“Socket”, mybytearray.toString());
                            curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                            timeString = formatter.format(curDate);
                            Log.e(“Socket”, “File read done!”);
                            dbHandler.addLog(“[*]”+timeString + “: Image has been chosenn”);
                            printDatabase();
                        } catch (IOException e) {
                            curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                            timeString = formatter.format(curDate);
                            Log.e(“Socket”, “File read error!”);
                            dbHandler.addLog(“[*]”+timeString + “: file read error!”);
                            printDatabase();
                        }
                        //輸出到電腦
                    } else {
                        curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                        timeString = formatter.format(curDate);
                        Log.e(“Socket”, “file doesn’t exist!”);
                        dbHandler.addLog(“[*]”+timeString + “: file doesn’t exist!”);
                        printDatabase();
                    }
                } else {
                    setTitle(“無效的檔案路徑 !!”);
                }
            } else {
                setTitle(“取消選擇檔案 !!”);
            }
        }
    }
    Runnable clientSocket = new Runnable() {
        @Override
        public void run() {
            try {
                serverAddr = InetAddress.getByName(“172.20.10.4”);
                serverPort = 5987;
                curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                timeString = formatter.format(curDate);
                Log.e(“Socket”, “Client: Connecting…”);
                dbHandler.addLog(“[*]”+ timeString + “: Client: Connecting…: ” + serverAddr + “/” + serverPort + “n”);
                //printDatabase();
                try {
                    socket = new Socket(serverAddr, serverPort);
                    outputstream = socket.getOutputStream();
                    outputstream.write(mybytearray, 0, mybytearray.length);
                    outputstream.flush();
                } catch (Exception e) {
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    Log.e(“Socket”, “Client: Error”, e);
                    dbHandler.addLog(“[*]”+timeString+ “: Client: Error” + e + “n”);
                    //printDatabase();
                } finally {
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    Log.e(“Socket”, “Transfer done!”);
                    dbHandler.addLog(“[*]”+timeString+ “: Transfer done!n”);
                    socket.close();
                }
            } catch (Exception e) {
                curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                timeString = formatter.format(curDate);
                Log.e(“Socket”, “Client: Error”, e);
                dbHandler.addLog(“[*]”+timeString+ “: Client: Error” + e + “n”);
                //printDatabase();
            }
        }
    };
    public void printDatabase(){
        String DBString = dbHandler.databaseToString();
        statusText.setText(DBString);
    }
}


3. MyDBHandler.java:

package com.javacourse.rongsonho.androidsocketclient;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
 * Created by RongSonHo on 5/24/16.
 */
public class MyDBHandler extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = “socket.db”;
    private static final String TABLE_LOG = “socket_log”;
    private static final String COLUME_ID = “_id”;
    private static final String COLUME_LOG= “socketLog”;
    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        String query = “CREATE TABLE ” + TABLE_LOG + ” ( ” +
                COLUME_ID + ” INTEGER PRIMARY KEY AUTOINCREMENT, ” +
                COLUME_LOG + ” TEXT ” +
                “);”;
        db.execSQL(query);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(“DROP TABLE IF EXISTS ” + TABLE_LOG);
        onCreate(db);
    }
    public String databaseToString(){
        String dbString = “”;
        SQLiteDatabase db = getWritableDatabase();
        String query = “SELECT * FROM ” + TABLE_LOG + ” WHERE 1″;
        Cursor cursor = db.rawQuery(query, null);
        cursor.moveToFirst();
        while(!cursor.isAfterLast()){
            if(cursor.getString(cursor.getColumnIndex(COLUME_LOG))!= null){
                dbString += cursor.getString(cursor.getColumnIndex(COLUME_LOG));
                dbString += “n”;
            }
            cursor.moveToNext();
        }
        db.close();
        return dbString;
    }
    public void addLog(String newlog){
        ContentValues values = new ContentValues();
        values.put(COLUME_LOG, newlog);
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_LOG, null, values);
        db.close();
    }
    public void deleteLog(){
        SQLiteDatabase db = getWritableDatabase();
        db.execSQL(“TRUNCATE TABLE ” + TABLE_LOG +”;” );
        db.close();
    }
}

4. MagicFileChooser.java: (別人寫好的工具,取自:https://magiclen.org/android-filechooser/)

package com.javacourse.rongsonho.androidsocketclient;

/**
 * Created by RongSonHo on 6/20/16.
 */
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
@SuppressLint(“NewApi”)
public class MagicFileChooser {
    public static final int ACTIVITY_FILE_CHOOSER = 9973;
    private final Activity activity;
    private boolean choosing = false;
    private boolean mustCanRead;
    private File[] chosenFiles;
    public MagicFileChooser(final Activity activity) {
        this.activity = activity;
    }
    public boolean showFileChooser() {
        return showFileChooser(“*/*”);
    }
    public boolean showFileChooser(final String mimeType) {
        return showFileChooser(mimeType, null);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle) {
        return showFileChooser(mimeType, chooserTitle, false);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple) {
        return showFileChooser(mimeType, chooserTitle, allowMultiple, false);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple, final boolean mustCanRead) {
        if (mimeType == null || choosing) {
            return false;
        }
        choosing = true;
        // 檢查是否有可用的Activity
        final PackageManager packageManager = activity.getPackageManager();
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType(mimeType);
        List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        if (list.size() > 0) {
            this.mustCanRead = mustCanRead;
            // 如果有可用的Activity
            Intent picker = new Intent(Intent.ACTION_GET_CONTENT);
            picker.setType(mimeType);
            picker.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple);
            picker.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
            // 使用Intent Chooser
            Intent destIntent = Intent.createChooser(picker, chooserTitle);
            activity.startActivityForResult(destIntent, ACTIVITY_FILE_CHOOSER);
            return true;
        } else {
            return false;
        }
    }
    public boolean onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (requestCode == ACTIVITY_FILE_CHOOSER) {
            choosing = false;
            if (resultCode == Activity.RESULT_OK) {
                Uri uri = data.getData();
                if (uri != null) {
                    // 單選
                    chosenFiles = getFilesFromUris(activity, new Uri[]{uri}, mustCanRead);
                    return true;
                } else if (Build.VERSION.SDK_INT >= 16) {
                    // 複選
                    ClipData clipData = data.getClipData();
                    if (clipData != null) {
                        int count = clipData.getItemCount();
                        if (count > 0) {
                            Uri[] uris = new Uri[count];
                            for (int i = 0; i < count; i++) {
                                uris[i] = clipData.getItemAt(i).getUri();
                            }
                            chosenFiles = getFilesFromUris(activity, uris, mustCanRead);
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    public File[] getChosenFiles() {
        return chosenFiles;
    }
    public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris) {
        return getAbsolutePathsFromUris(context, uris, false);
    }
    public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
        File[] files = getFilesFromUris(context, uris, mustCanRead);
        int filesLength = files.length;
        String[] paths = new String[filesLength];
        for (int i = 0; i < filesLength; i++) {
            paths[i] = files[i].getAbsolutePath();
        }
        return paths;
    }
    public static File[] getFilesFromUris(final Context context, final Uri[] uris) {
        return getFilesFromUris(context, uris, false);
    }
    public static File[] getFilesFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
        ArrayList<File> fileList = new ArrayList<File>();
        int urisLength = uris.length;
        for (int i = 0; i < urisLength; i++) {
            Uri uri = uris[i];
            File file = getFileFromUri(context, uri, mustCanRead);
            if (file != null) {
                fileList.add(file);
            }
        }
        File[] files = new File[fileList.size()];
        fileList.toArray(files);
        return files;
    }
    public static String getAbsolutePathFromUri(final Context context, final Uri uri) {
        return getAbsolutePathFromUri(context, uri, false);
    }
    public static String getAbsolutePathFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
        File file = getFileFromUri(context, uri, mustCanRead);
        if (file != null) {
            return file.getAbsolutePath();
        } else {
            return null;
        }
    }
    public static File getFileFromUri(final Context context, final Uri uri) {
        return getFileFromUri(context, uri, false);
    }
    @SuppressLint(“NewApi”)
    public static File getFileFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
        if (uri == null) {
            return null;
        }
        // 判斷是否為Android 4.4之後的版本
        final boolean after44 = Build.VERSION.SDK_INT >= 19;
        if (after44 && DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是Android 4.4之後的版本,而且屬於文件URI
            final String authority = uri.getAuthority();
            // 判斷Authority是否為本地端檔案所使用的
            if (“com.android.externalstorage.documents”.equals(authority)) {
                // 外部儲存空間
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] divide = docId.split(“:”);
                final String type = divide[0];
                if (“primary”.equals(type)) {
                    String path = Environment.getExternalStorageDirectory() + “/” + divide[1];
                    return createFileObjFromPath(path, mustCanRead);
                }
            } else if (“com.android.providers.downloads.documents”.equals(authority)) {
                // 下載目錄
                final String docId = DocumentsContract.getDocumentId(uri);
                final Uri downloadUri = ContentUris.withAppendedId(Uri.parse(“content://downloads/public_downloads”), Long.parseLong(docId));
                String path = queryAbsolutePath(context, downloadUri);
                return createFileObjFromPath(path, mustCanRead);
            } else if (“com.android.providers.media.documents”.equals(authority)) {
                // 圖片、影音檔案
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] divide = docId.split(“:”);
                final String type = divide[0];
                Uri mediaUri = null;
                if (“image”.equals(type)) {
                    mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if (“video”.equals(type)) {
                    mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if (“audio”.equals(type)) {
                    mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                } else {
                    return null;
                }
                mediaUri = ContentUris.withAppendedId(mediaUri, Long.parseLong(divide[1]));
                String path = queryAbsolutePath(context, mediaUri);
                return createFileObjFromPath(path, mustCanRead);
            }
        } else {
            // 如果是一般的URI
            final String scheme = uri.getScheme();
            String path = null;
            if (“content”.equals(scheme)) {
                // 內容URI
                path = queryAbsolutePath(context, uri);
            } else if (“file”.equals(scheme)) {
                // 檔案URI
                path = uri.getPath();
            }
            return createFileObjFromPath(path, mustCanRead);
        }
        return null;
    }
    public static File createFileObjFromPath(final String path) {
        return createFileObjFromPath(path, false);
    }
    public static File createFileObjFromPath(final String path, final boolean mustCanRead) {
        if (path != null) {
            try {
                File file = new File(path);
                if (mustCanRead) {
                    file.setReadable(true);
                    if (!file.canRead()) {
                        return null;
                    }
                }
                return file.getAbsoluteFile();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }
    public static String queryAbsolutePath(final Context context, final Uri uri) {
        final String[] projection = {MediaStore.MediaColumns.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                return cursor.getString(index);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }
}


參考文章:

1. Android 如何選取圖片或是檔案?:https://magiclen.org/android-filechooser/
2. 西加加 Android 手機資料傳到電腦: http://pianovv510.blogspot.tw/2013/04/android-wifi.html
3. Android TextView多行本文滾動輕鬆實現:http://sunylin.pixnet.net/blog/post/91068996-android-textview多行本文滾動輕鬆實現