——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
在线程中,有时候会出现安全问题,就是一个线程的代码还没执行完,CPU就把执行权分配给了其他线程,导致数据出现错误。这些问题我们应该怎么解决呢?
我们可以用到同步来解决。它能让一个线程执行完,在执行过程中,其他线程不可以参与执行。
同步的关键字是 synchronized
同步包括两方面,可以是同步代码块,也可以是同步函数。
第一种,同步代码块:格式如下
synchronized ( 对象 )
{
需要被同步的代码;
}
这里的对象可以是任意对象,譬如 new Object ( ) ,它相当于一个锁。
第二种,同步函数。
其实就是所需要同步的函数用 synchronized 关键字修饰。
同步函数使用的锁是 this
有特殊情况,如果同步函数被静态修饰后,使用的锁是该方法所在类的字节码文件对象。 (类名 . class)
死锁:同步中嵌套同步,多个线程间相互占用着锁,等待对方的锁运行,导致线程都停滞不动的情况。我们要避免这种情况的发生。
譬如下面就是一个死锁的例子:
public class DeadLockTest {
public static void main(String[] args){
DeadLock d1=new DeadLock(true);
DeadLock d2=new DeadLock(false);
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
t1.start();
t2.start();
}
}
class DeadLock implements Runnable{
private boolean flag;
DeadLock(boolean flag){
this.flag=flag;
}
public void run(){
if(flag){
synchronized(Lock.locka){
System.out.println("if locka");
synchronized(Lock.lockb){
System.out.println("if lockb");
}
}
}else{
synchronized(Lock.lockb){
System.out.println("else lockb");
synchronized(Lock.locka){
System.out.println("else locka");
}
}
}
}
}
class Lock{
static Object locka=new Object();
static Object lockb=new Object();
}
等待唤醒机制:
都使用在同步中,因为要对持有锁的线程进行操作。
主要用到的方法有 wait( ) 、notify ( )、notifyAll ( ) 。
public class DengdaiHuanxing2 {
public static void main(String[] args){
Rec r=new Rec();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}
class Rec{
private String name;
private String sex;
boolean flag=false;
public synchronized void setRec(String name,String sex){
if(flag)
try{wait();}catch(Exception e){}
this.name=name;
this.sex=sex;
flag=true;
notify();
}
public synchronized void out(){
if(!flag)
try{wait();}catch(Exception e){}
System.out.println(name+"....."+sex);
flag=false;
notify();
}
}
class Input implements Runnable{
private Rec r;
Input(Rec r){
this.r=r;
}
public void run(){
int x=0;
while(true){
if(x==0){
r.setRec("Mike", "man");
}else{
r.setRec("丽丽","女生");
}
x=(x+1)%2;
}
}
}
class Output implements Runnable{
private Rec r;
Output(Rec r){
this.r=r;
}
public void run(){
while(true){
r.out();
}
}
}