概念
解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一时间段内只能有一个线程执行代码,其他线程要等待此线程完成之后才可以继续执行。
方法
线程进行同步,有以下两种方法:
(1)同步代码块
synchronized(要同步的对象){
要同步的操作;
}
(2)同步方法
public synchronized void method(){
要同步的操作;
}
同步代码块示例:
package 线程同步与死锁;
public class Example {
public static void main(String[] args) {
MyThread my=new MyThread();
Thread t1=new Thread(my,"小白");
Thread t2=new Thread(my,"小红");
t1.start();
t2.start();
}
}
class MyThread implements Runnable{
Object obj=new Object();//同步的标记对象,可以设置为任意对象
public void run() {
/*
* 同步代码块
* 当某一线程运行至同步代码块时,obj的赋值将会改变
* 比如没有线程进入同步代码块时,obj==0,表示代码块为开放状态
* 当有线程运行至同步代码块时,obj==1,
* 表示代码块为上锁状态,不允许其他线程进入
*
*/
synchronized (obj) {
System.out.println(Thread.currentThread().getName()+"正在出恭……");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"出恭完毕……");
}
}
同步方法示例:
package 线程同步与死锁;
public class Example {
public static void main(String[] args) {
MyThread my=new MyThread();
Thread t1=new Thread(my,"小白");
Thread t2=new Thread(my,"小红");
t1.start();
t2.start();
}
}
class MyThread implements Runnable{
Object obj=new Object();//同步的标记对象,可以设置为任意对象
public void run() {
doMethod();
}
/*
* 同步方法,标记对象当前对象(this)
* 当同时又若干个同步方法时,this却只有一个
* this被使用时会上锁(也就是进行赋值标记),
* 确保同步方法不会同时执行多个
*
*/
public synchronized void doMethod(){
System.out.println(Thread.currentThread().getName()+"正在出恭……");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"出恭完毕……");
}
}
注意
当编写synchronized块时,有几个简单的准则可以遵循,这些准则在避免死锁性能危险的风险方面大有帮助
(1)使代码块保持简短,把不需要同步的代码移出代码块
(2)不要阻塞。如在代码块中使用InputStream.read()。
(3) 在代码块中,尽量不要再调用其他类中声明的方法,防止死锁