线程同步
Java中允许多线程bing并行访问,同一个时间段内多个线程同时完成各自的操作。
多个线程同时操作同一个共享数据时,可能会导致数据不准确的问题
使用线程同步可以解决上述问题
可以通过synchronized关键字修饰方法实现线程同步,每个Java对象都有一个内置锁,内置锁会保护使用synchronized关键字修饰的方法,要调用该方法就必须先获得锁,否则就处于阻塞状态
非线程同步
public class Account implements Runnable {
private static int num;
@Override
public void run() {
num++;
// 休眠1秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印输出
System.out.println(Thread.currentThread().getName()+"是当前的第"+num+"位访问");
}
public static void main(String[] args) {
Account account = new Account();
Thread t1 = new Thread(account, "张三");
Thread t2 = new Thread(account, "李四");
for (int i = 0; i <10 ; i++) {
new Thread(account,"线程"+i).start();
}
}
}
线程同步代码
public class Account implements Runnable {
private static int num;
@Override
public synchronized void run() {
num++;
// 休眠1秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印输出
System.out.println(Thread.currentThread().getName()+"是当前的第"+num+"位访问");
}
public static void main(String[] args) {
Account account = new Account();
Thread t1 = new Thread(account, "张三");
Thread t2 = new Thread(account, "李四");
for (int i = 0; i <10 ; i++) {
new Thread(account,"线程"+i).start();
}
}
}
synchronized关键字可以修饰实例方法,也可以修饰静态方法,两者在使用的时候是有区别·的
synchronized修饰非静态方法
给实例方法(非静态方法)添加synchronized关键字并不能实现线程同步。
线程同步的本质是锁定多个线程所共享的资源,synchronized还可以修饰代码块,会为代码块加上内置锁,从而实现同步
public class SynchronizedTest03 {
public static void main(String[] args) {
for (int i = 0; i <5 ; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
SynchronizedTest03.test();
}
});
thread.start();
}
}
public static void test(){
synchronized (SynchronizedTest03.class){
System.out.println("start...");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
如何判断线程同步或者是不同步?
找到关键点:锁定的资源在内存中是一份还是多份?一份需要大家排队,线程同步,多份(一人一份)线程不同步。
无论是锁定方法还是锁定对象,锁定类,只需要分析这个方法、对象、类在内存中存在几份即可
对象一般都是多份
类一定是一份
方法就看是静态方法还是非静态方法,静态方法一定是一份,非静态方法一般是多份