线程同步
为什么会出现线程同步这个概念呢?我们都知道线程是进程的基本运行单位,进程与进程之间是相互隔离互不影响的,拥有自己的独立空间,一个进程拥有多个线程,二线程与线程之间是共享虚拟空间和静态资源等的,这就导致当多个线程共享同一个资源的时候,会出现数据安全,资源冲突线程线程,而线程同步这个机制的出现就是为了解决这一问题的
当多线程共享统一资源不设置线程同步的时候例如下:
public class Account implements Runnable {
private static int num;
@Override
public void run() {
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
num++;
System.out.println(Thread.currentThread().getName()+"是第"+num+"位访客");
}
}
public class Test1 {
public static void main(String[] args) {
Account account = new Account();
Thread threadA = new Thread(account,"A线程");
Thread threadB = new Thread(account,"B线程");
threadA.start();
threadB.start();
}
}
B线程是第2位访客
A线程是第2位访客
分析以上问题我们会发现,A、B两个线程共享num这一个静态数据,正常情况下这个输出结果应该是一个线程是第1位访客,一个线程是第2为访客,但是结果却都是第2位访客,这就与我们的意愿背道而驰,为什么会出现这种情况呢?当B线程获取的cpu的时候会进入到run方法然后num++,这时候num是1,但是当他还没有输出结果的时候A线程进来了,也进行了一次num++,这时候num变成了2,这是后B才输出,所以结果是2,A线程输出的num也是2,这就导致了数据错误。所以为了避免这种问题的发生,我们要保证一个线程在操作共享资源的时候,其他线程不能对这个贡献资源进行操作,这就用到了线程同步。
解决方案
在方法上加synchronized关键字来修饰方法实现线程同步,每一个java对象都有一个内置锁,内置锁会保护被synchronized修饰的方法不被其他线程所访问,要进入这个方法就必须拥有这个内置锁,否则就会处于阻塞状态。
一下是synchronized修饰对象方法:
public class Account implements Runnable {
private static int num;
@Override
public synchronized void run() {
System.out.println("当前对象是"+this);
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
num++;
System.out.println(</