Java学习34-Java 多线程Thread 同步方法

同部方法

使用同步方法块,依旧是为了解决线程安全问题。

说明:如果操作共享数据的代码完整的声明在了一个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

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值