同步-同步锁-死锁-线程交互-线程综合示例

一、同步

1.作用:为了避免多个线程同时访问并修改共享数据所导致的不安全问题。

2.使用synchronized(对象){}方式。

二、机制

1.当线程要进入某个被“同步锁”锁住代码之前,线程必须先获得“同步锁对象”

2.保证任何时刻,只有一条线程能执行被锁代码

3.不许以“竞争资源”作为“同步对象”

三、同步锁的释放

1.代码完成

2.语句块抛出异常

3.语句块遇到break,return

4.调用wait方法

5.注意:sleep和yield方法不会释放同步锁

四、对象锁池

新建->start()->可运行<---调度任务--> 正在运行->run()完成->终止

正在运行---阻塞事件(sleep,join)----->阻塞-----解除阻塞---->可运行

正在运行---同步的------>阻塞对象的锁池-----获得所---->可运行

五、代码演示

package 同步;

public class Couner implements Runnable{
    private int counter=200;
    public void run() {
        for(int i = 0;i<50;i++){
            synchronized (this) {
                
                counter-=2;
                try {Thread.sleep(10);} catch (InterruptedException e) {}
                System.out.print(counter+"   ");
            }
        }
        
        
    }
}
package 同步;

public class TestCounersyc {
    public static void main(String[] args) {
        Couner c = new Couner();
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start();
    }
}

六、死锁

1.定义:两个线程都在等待对方执行完毕才能往下执行时发生死锁,陷入无限等待中。

2.解决:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。

3.死锁代码案例

package 死锁;

public class DeadLock
{
    private final Object left = new Object();
    private final Object right = new Object();
    
    public void leftRight() throws Exception
    {
        synchronized (left)
        {
            Thread.sleep(2000);
            synchronized (right)
            {
                System.out.println("leftRight end!");
            }
        }
    }
    
    public void rightLeft() throws Exception
    {
        synchronized (right)
        {
            Thread.sleep(2000);
            synchronized (left)
            {
                System.out.println("rightLeft end!");
            }
        }
    }
}
package 死锁;

public class Thread0 extends Thread
{
    private DeadLock dl;
    
    public Thread0(DeadLock dl)
    {
        this.dl = dl;
    }
    
    public void run()
    {
        try
        {
            dl.leftRight();
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
package 死锁;

public class Thread1 extends Thread
{
    private DeadLock dl;
    
    public Thread1(DeadLock dl)
    {
        this.dl = dl;
    }
    
    public void run()
    {
        try
        {
            dl.rightLeft();
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
package 死锁;

public class Test {
    public static void main(String[] args)
    {
        DeadLock dl = new DeadLock();
        Thread0 t0 = new Thread0(dl);
        Thread1 t1 = new Thread1(dl);
        t0.start();
        t1.start();

        while(true);   
    }
}


七、线程交互

1.wait方法使线程进入阻塞状态,直到线程得到唤醒通知,或者达到指定时间。

注意:

1)wait和notify方法仅能在所访问对象的同步块内调用。

2)当线程调用wait方法进入等待状态时,会释放对象锁标记。

2.唤醒方式

  通知唤醒-notify或notifyAll方法

  主动唤醒-到达阻塞事件

  中断唤醒-被另一个线程调用interrupt方法,收到InterruptedException异常。

3.代码演示

 

package 线程交互;

public class Couner implements Runnable{
    private int counter=0;
    
    public void setCounter(int counter){
        this.counter = counter;
    }
    
    public synchronized void run() {
        if(counter<100){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        counter-=100;
        System.out.println("counter = " + counter);
        System.out.println("Counter线程结束");
    }
}

 

package 线程交互;


public class TestCounerWait {
    public static void main(String[] args) {
        Couner c = new Couner();
        Thread t = new Thread(c);
        t.start();
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        
        synchronized (c) {
            c.setCounter(150);
            c.notify();
        }
        System.out.println("main线程结束");
    }
}

八、线程综合示例(代码)

 

package 线程综合示例;

public class Couner{
    private int counter=0;
    
    public synchronized int increase(int n){
        counter+=n;
        this.notify();
        System.out.printf("生产:couner=%-2d n=%-2d\n",counter,n);
        return counter;
    }
    
    
    public synchronized int decrease(int n){
        while(counter<n){
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        
        counter-=n;
        System.out.printf("消费:couner=%-2d n=%-2d\n",counter,n);
        return counter;
    }
    
}

 

package 线程综合示例;

public class Producer implements Runnable{
    private Couner couner;
    
    public Producer(Couner couner){
        this.couner = couner;
    }
    
    public void run() {
        for(int i=0;i<50;i++){
            couner.increase((int)(Math.random()*10));
            try {
                Thread.sleep((int)(Math.random()*100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            
        }
    }
        
}

 

package 线程综合示例;

public class Consumer implements Runnable{

    private Couner couner;
    
    public Consumer(Couner couner){
        this.couner = couner;
    }
    
    public void run() {
        for(int i=0;i<50;i++){
            couner.decrease((int)(Math.random()*8));
            try {
                Thread.sleep((int)(Math.random()*100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            
        }
    }
        

}

 

package 线程综合示例;


public class TestPC {
    public static void main(String[] args) {
        Couner couner = new Couner();
        
        
        Producer p = new Producer(couner);
        Thread t1 = new Thread(p);
        Consumer c = new Consumer(couner);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start();
    }
}

 

posted @ 2017-08-01 17:07  非凡起航  阅读(224)  评论(0编辑  收藏  举报