java多线程-synchronized

synchronized是Java中使用的最基本的一个同步方法,使用 synchronized关键字来控制并发访问方法。只有一个执行线程将会访问一个对象中被synchronized关键字声明的方法。如果另一个线程试图访问同一个对象中任何被synchronized关键字声明的方法,它将被暂停,直到第一个线程结束方法的执行。

每个方法声明为synchronized关键字是一个临界区,Java只允许一个对象执行其中的一个临界区。

静态方法有不同的行为。只有一个执行线程访问被synchronized关键字声明的静态方法,但另一个线程可以访问该类的一个对象中的其他非静态的方法。 你必须非常小心这一点,因为两个线程可以访问两个不同的同步方法,如果其中一个是静态的而另一个不是。如果这两种方法改变相同的数据,你将会有数据不一致 的错误

同一个类中有多个synchronized关键字声明的静态方法。只要有一个线程访问了其中一个,其它线程则不可以访问任务一个synchronized关键字声明的静态方法,但可以访问该类其它同步方法和普通方法。

示例:

import java.util.Scanner;

public class SynchronizedTest {

    public static synchronized void test1(){
        System.out.println(Thread.currentThread().getName()+"进入阻塞!任意键结束!");
        Scanner a = new Scanner(System.in);
        a.next();

    }

    public static synchronized void test2(){
        System.out.println(Thread.currentThread().getName()+"进入阻塞!任意键结束!");
        Scanner a = new Scanner(System.in);
        a.next();
    }

    public synchronized void test3(){
        System.out.println(Thread.currentThread().getName()+"开始运行!");
        System.out.println(Thread.currentThread().getName()+"请稍等...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"运行结束!");
    }

    public void test4(){
        System.out.println(Thread.currentThread().getName()+"没有阻塞,运行结束!");
    }

    public static void main(String[] args) {
        Thread a = new Thread(new Runnable(){
            @Override
            public void run() {
                SynchronizedTest.test1();
            }
        });

        Thread b = new Thread(new Runnable(){
            @Override
            public void run() {
                SynchronizedTest.test2();
            }
        });

        Thread c = new Thread(new Runnable(){
            @Override
            public void run() {
                new SynchronizedTest().test3();
            }
        });

        Thread d = new Thread(new Runnable(){
            @Override
            public void run() {
                new SynchronizedTest().test3();;
            }
        });

        Thread e = new Thread(new Runnable(){
            @Override
            public void run() {
                new SynchronizedTest().test4();;
            }
        });

        final SynchronizedTest syn = new SynchronizedTest();
        Thread f = new Thread(new Runnable(){
            @Override
            public void run() {
                syn.test3();;
            }
        });

        Thread g = new Thread(new Runnable(){
            @Override
            public void run() {
                syn.test3();;
            }
        });

        a.setName("线程1");
        b.setName("线程2");
        c.setName("线程3(与线程4不同对象的同一任务)");
        d.setName("线程4(与线程3不同对象的同一任务)");
        e.setName("线程5");
        f.setName("线程6(与线程7同对象的同一任务)");
        g.setName("线程7(与线程6同对象的同一任务)");

        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
        f.start();
        g.start();

    }
}

结果:

线程1进入阻塞!任意键结束!
线程4(与线程3不同对象的同一任务)开始运行!
线程4(与线程3不同对象的同一任务)请稍等...
线程6(与线程7同对象的同一任务)开始运行!
线程6(与线程7同对象的同一任务)请稍等...
线程3(与线程4不同对象的同一任务)开始运行!
线程3(与线程4不同对象的同一任务)请稍等...
线程5没有阻塞,运行结束!
线程4(与线程3不同对象的同一任务)运行结束!
线程6(与线程7同对象的同一任务)运行结束!
线程3(与线程4不同对象的同一任务)运行结束!
线程7(与线程6同对象的同一任务)开始运行!
线程7(与线程6同对象的同一任务)请稍等...
线程7(与线程6同对象的同一任务)运行结束!
d
线程2进入阻塞!任意键结束!
d

可以看到:
线程6与线程7 排队执行
线程3与线程6 没有排队
线程1与线程2 排队执行
线程1阻塞时,其它非静态方法都能顺利执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值