同部方法
使用同步方法块,依旧是为了解决线程安全问题。
说明:如果操作共享数据的代码完整的声明在了一个method方法中,那么我们就可以将此方法声明为同步方法。换言之,synchronized结构块全部包裹在method里,就把这个method叫同步method。
第一种,使用implements Runnable方法作出同步method:
package Thread;
public class WindowTestMethod {
public static void main(String[] args) {
SaleTickM x = new SaleTickM();
Thread t1= new Thread(x);
Thread t2= new Thread(x);
Thread t3= new Thread(x);
t1.start();
t2.start();
t3.start();
}
}
class SaleTickM implements Runnable{
boolean break_flag = false;
static int tickets =100;
public synchronized void show(){//此时的同步监视器是:this(这是系统默认的,改不了)。
// 此题目中只生成了一个 SaleTickM x ,确实唯一的,这里可以用this没啥问题。
// 用户要注意判断,有时候并不是唯一的。
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling ticket NO. " + tickets);
tickets--;
Thread.yield();
}
else break_flag = true;
}
@Override
public void run() {
while(break_flag == false) {
// synchronized (SaleTickM.class) {
show();
//}
}
}
}
运行结果:
Thread-0 is selling ticket NO. 100
Thread-0 is selling ticket NO. 99
Thread-0 is selling ticket NO. 98
Thread-0 is selling ticket NO. 97
Thread-0 is selling ticket NO. 96
Thread-0 is selling ticket NO. 95
Thread-0 is selling ticket NO. 94
Thread-0 is selling ticket NO. 93
Thread-0 is selling ticket NO. 92
Thread-0 is selling ticket NO. 91
Thread-0 is selling ticket NO. 90
Thread-0 is selling ticket NO. 89
Thread-0 is selling ticket NO. 88
Thread-0 is selling ticket NO. 87
Thread-0 is selling ticket NO. 86
Thread-0 is selling ticket NO. 85
Thread-0 is selling ticket NO. 84
Thread-0 is selling ticket NO. 83
Thread-0 is selling ticket NO. 82
Thread-0 is selling ticket NO. 81
Thread-0 is selling ticket NO. 80
Thread-0 is selling ticket NO. 79
Thread-0 is selling ticket NO. 78
Thread-0 is selling ticket NO. 77
Thread-0 is selling ticket NO. 76
Thread-0 is selling ticket NO. 75
Thread-0 is selling ticket NO. 74
Thread-0 is selling ticket NO. 73
Thread-0 is selling ticket NO. 72
Thread-0 is selling ticket NO. 71
Thread-0 is selling ticket NO. 70
Thread-0 is selling ticket NO. 69
Thread-0 is selling ticket NO. 68
Thread-0 is selling ticket NO. 67
Thread-0 is selling ticket NO. 66
Thread-0 is selling ticket NO. 65
Thread-2 is selling ticket NO. 64
Thread-2 is selling ticket NO. 63
Thread-2 is selling ticket NO. 62
Thread-2 is selling ticket NO. 61
Thread-2 is selling ticket NO. 60
Thread-2 is selling ticket NO. 59
Thread-2 is selling ticket NO. 58
Thread-2 is selling ticket NO. 57
Thread-2 is selling ticket NO. 56
Thread-2 is selling ticket NO. 55
Thread-2 is selling ticket NO. 54
Thread-2 is selling ticket NO. 53
Thread-2 is selling ticket NO. 52
Thread-2 is selling ticket NO. 51
Thread-2 is selling ticket NO. 50
Thread-2 is selling ticket NO. 49
Thread-2 is selling ticket NO. 48
Thread-2 is selling ticket NO. 47
Thread-2 is selling ticket NO. 46
Thread-2 is selling ticket NO. 45
Thread-2 is selling ticket NO. 44
Thread-2 is selling ticket NO. 43
Thread-2 is selling ticket NO. 42
Thread-2 is selling ticket NO. 41
Thread-2 is selling ticket NO. 40
Thread-2 is selling ticket NO. 39
Thread-2 is selling ticket NO. 38
Thread-2 is selling ticket NO. 37
Thread-2 is selling ticket NO. 36
Thread-2 is selling ticket NO. 35
Thread-2 is selling ticket NO. 34
Thread-2 is selling ticket NO. 33
Thread-2 is selling ticket NO. 32
Thread-2 is selling ticket NO. 31
Thread-2 is selling ticket NO. 30
Thread-2 is selling ticket NO. 29
Thread-2 is selling ticket NO. 28
Thread-2 is selling ticket NO. 27
Thread-2 is selling ticket NO. 26
Thread-2 is selling ticket NO. 25
Thread-2 is selling ticket NO. 24
Thread-2 is selling ticket NO. 23
Thread-2 is selling ticket NO. 22
Thread-2 is selling ticket NO. 21
Thread-2 is selling ticket NO. 20
Thread-2 is selling ticket NO. 19
Thread-2 is selling ticket NO. 18
Thread-2 is selling ticket NO. 17
Thread-2 is selling ticket NO. 16
Thread-2 is selling ticket NO. 15
Thread-2 is selling ticket NO. 14
Thread-2 is selling ticket NO. 13
Thread-2 is selling ticket NO. 12
Thread-2 is selling ticket NO. 11
Thread-2 is selling ticket NO. 10
Thread-2 is selling ticket NO. 9
Thread-2 is selling ticket NO. 8
Thread-2 is selling ticket NO. 7
Thread-2 is selling ticket NO. 6
Thread-2 is selling ticket NO. 5
Thread-2 is selling ticket NO. 4
Thread-2 is selling ticket NO. 3
Thread-2 is selling ticket NO. 2
Thread-2 is selling ticket NO. 1
Process finished with exit code 0
第二种方式,同样的卖票例子,使用implements Thread完成同步method。
package Thread;
public class WindowTestMethod1 {
public static void main(String[] args) {
SaleTickThread x= new SaleTickThread();
x.start();
SaleTickThread y= new SaleTickThread();
y.start();
SaleTickThread z= new SaleTickThread();
z.start();
}
}
class SaleTickThread extends Thread{
static int tickets = 100;
static boolean ticket_valid = true; //注意这里的flag也常用static标注上
//public synchronized void show(){//此时同步监视器:this,此题目中为:x,y,z,所以并不是唯一的,在这里不能约束线程
static public synchronized void show(){//静态方法的同步监视器:默认是当前类,这里就是SaleTickThread.class,此题目中,确实是唯一的,可以在这里约束线程
// 注意,有时候写synchronized关键字,但是内置变量并不单一(this或者current.class),无法满足来约束线程的目的,
// 那么建议用户找到唯一的变量,将对应代码块手动包裹起来达到约束功能
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling ticket No. " + tickets);
tickets--;
Thread.yield();
}
else ticket_valid = false;
}
@Override
public void run() {
while(ticket_valid) {
//synchronized (SaleTickThread.class){}
show();
}
}
}
运行结果:
Thread-0 is selling ticket No. 100
Thread-1 is selling ticket No. 99
Thread-1 is selling ticket No. 98
Thread-1 is selling ticket No. 97
Thread-1 is selling ticket No. 96
Thread-1 is selling ticket No. 95
Thread-1 is selling ticket No. 94
Thread-1 is selling ticket No. 93
Thread-1 is selling ticket No. 92
Thread-1 is selling ticket No. 91
Thread-1 is selling ticket No. 90
Thread-1 is selling ticket No. 89
Thread-1 is selling ticket No. 88
Thread-1 is selling ticket No. 87
Thread-1 is selling ticket No. 86
Thread-1 is selling ticket No. 85
Thread-1 is selling ticket No. 84
Thread-1 is selling ticket No. 83
Thread-1 is selling ticket No. 82
Thread-1 is selling ticket No. 81
Thread-1 is selling ticket No. 80
Thread-1 is selling ticket No. 79
Thread-1 is selling ticket No. 78
Thread-1 is selling ticket No. 77
Thread-1 is selling ticket No. 76
Thread-1 is selling ticket No. 75
Thread-1 is selling ticket No. 74
Thread-1 is selling ticket No. 73
Thread-1 is selling ticket No. 72
Thread-1 is selling ticket No. 71
Thread-1 is selling ticket No. 70
Thread-1 is selling ticket No. 69
Thread-1 is selling ticket No. 68
Thread-1 is selling ticket No. 67
Thread-1 is selling ticket No. 66
Thread-1 is selling ticket No. 65
Thread-1 is selling ticket No. 64
Thread-1 is selling ticket No. 63
Thread-1 is selling ticket No. 62
Thread-1 is selling ticket No. 61
Thread-1 is selling ticket No. 60
Thread-1 is selling ticket No. 59
Thread-1 is selling ticket No. 58
Thread-1 is selling ticket No. 57
Thread-1 is selling ticket No. 56
Thread-1 is selling ticket No. 55
Thread-1 is selling ticket No. 54
Thread-1 is selling ticket No. 53
Thread-1 is selling ticket No. 52
Thread-1 is selling ticket No. 51
Thread-1 is selling ticket No. 50
Thread-1 is selling ticket No. 49
Thread-1 is selling ticket No. 48
Thread-1 is selling ticket No. 47
Thread-2 is selling ticket No. 46
Thread-2 is selling ticket No. 45
Thread-2 is selling ticket No. 44
Thread-2 is selling ticket No. 43
Thread-2 is selling ticket No. 42
Thread-2 is selling ticket No. 41
Thread-2 is selling ticket No. 40
Thread-2 is selling ticket No. 39
Thread-2 is selling ticket No. 38
Thread-2 is selling ticket No. 37
Thread-2 is selling ticket No. 36
Thread-2 is selling ticket No. 35
Thread-2 is selling ticket No. 34
Thread-2 is selling ticket No. 33
Thread-2 is selling ticket No. 32
Thread-2 is selling ticket No. 31
Thread-2 is selling ticket No. 30
Thread-2 is selling ticket No. 29
Thread-2 is selling ticket No. 28
Thread-2 is selling ticket No. 27
Thread-2 is selling ticket No. 26
Thread-2 is selling ticket No. 25
Thread-2 is selling ticket No. 24
Thread-2 is selling ticket No. 23
Thread-2 is selling ticket No. 22
Thread-2 is selling ticket No. 21
Thread-2 is selling ticket No. 20
Thread-2 is selling ticket No. 19
Thread-2 is selling ticket No. 18
Thread-2 is selling ticket No. 17
Thread-2 is selling ticket No. 16
Thread-2 is selling ticket No. 15
Thread-2 is selling ticket No. 14
Thread-2 is selling ticket No. 13
Thread-2 is selling ticket No. 12
Thread-2 is selling ticket No. 11
Thread-2 is selling ticket No. 10
Thread-2 is selling ticket No. 9
Thread-2 is selling ticket No. 8
Thread-2 is selling ticket No. 7
Thread-2 is selling ticket No. 6
Thread-2 is selling ticket No. 5
Thread-2 is selling ticket No. 4
Thread-2 is selling ticket No. 3
Thread-2 is selling ticket No. 2
Thread-2 is selling ticket No. 1
Process finished with exit code 0
说明:如果操作共享数据的代码完整的声明在了一个方法中,那么我们就可以经此方法声明为同步方法即可
非静态的同步方法,默认同步监视器是this
静态的同步方法,默认同步监视器是当前类本身。
synchronized的好处:解决了线程的安全问题
弊端:在操作共享数据时,多线程其实是串行执行的,意味着浪费CPU性能低。
自由练习题:
输出倒计时10-1,最后输出-新年快乐,每次间隔1秒。
package Thread;
public class HappyNewYear {
public static void main(String[] args) throws InterruptedException {
while(true){
for (int i = 10; i > 0; i--) {
System.out.println(i);
Thread.sleep(1000);
if(i==1){
System.out.println("Happy New Year!");
}
}
break;
}
}
}
输出结果:
10
9
8
7
6
5
4
3
2
1
Happy New Year!
例题:俩人都去一个账户存钱,一次存1000,每次存完打印余额。每人存3次。
package Thread;
public class BankStore {
public static void main(String[] args) {
BankCount x= new BankCount();
Thread t1 = new Thread(x);
Thread t2 = new Thread(x);
t1.start();
t2.start();
}
}
class BankCount implements Runnable{
static int money = 0;
@Override
public void run() {
for (int i = 0; i < 3; i++) {
synchronized (BankCount.class){
save();
Thread.yield();}
}
}
public void save(){
money+=1000;
System.out.println(Thread.currentThread().getName()+" :Current account saving is "+ money);
}
}
输出为:
Thread-0 :Current account saving is 1000
Thread-1 :Current account saving is 2000
Thread-1 :Current account saving is 3000
Thread-1 :Current account saving is 4000
Thread-0 :Current account saving is 5000
Thread-0 :Current account saving is 6000
Process finished with exit code 0