Java多线程(二)

Java多线程(一):
https://blog.csdn.net/Veer_c/article/details/103842078
Java多线程(二):
https://blog.csdn.net/Veer_c/article/details/103842263
Java多线程(三):
https://blog.csdn.net/Veer_c/article/details/103842317
Java多线程(四):
https://blog.csdn.net/Veer_c/article/details/103842602
java

案例:利用匿名内部类,启动多个线程,验证单例设计模式之懒汉式所存在的缺陷,web

public class SingleIntanceDemo {
    //私有化构造
    private SingleIntanceDemo(){}
    private static SingleIntanceDemo instance = null;
    public  static SingleIntanceDemo getInstance(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (instance==null) {
            instance = new SingleIntanceDemo();
        }
        return instance;
    }
}
public class Test {
    public static void main(String[] args) {
        //启动第一个线程
        new Thread(){
            @Override
            public void run() {                
            	System.out.println(SingleIntanceDemo.getInstance());
                //com.edu_12.SingleIntanceDemo@2d7fc1e7
            }
        }.start();
        //启动第二个线程
        new Thread(){
            public void run() {              
            	System.out.println(SingleIntanceDemo.getInstance());
                //com.edu_12.SingleIntanceDemo@2a8b83e3
            };
        }.start();
    }
}

当咱们利用多线程来验证单例模式的时候,发现俩个对象的地址值不一样,即不是同一个对象,咱们能够利用同步方法来改进
在建立对象的方法上加上 synchronized关键字就能够
(9)JDK5的Lock锁,咱们以前造的全部的锁都没有手动释放锁
static Lock lock = new ReentrantLock();
上枷锁:lock.lock();
释放锁:lock.unlock();
能够让咱们明确的知道在哪里加锁和释放锁。
依然写一个卖票的案例,用lock枷锁释放锁,
为了保证咱们建立的锁必定会被释放,用一下代码进行改进
try{….}finally{……}设计模式

public class MyThread implements Runnable{
    //定义100张票
    int ticket = 100;
    Object obj = new Object();
    //建立一个锁
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true) {
            try{
                //加上锁,获取锁
                lock.lock();
                if (ticket>0) {
                        //考虑到实际的生活中,咱们须要给每个线程加入必定的延迟,模拟一下这种效果
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"正在出售第:"+ticket--+"张票");
                    }
            }finally{
                //这里面的代码必定会被执行
                //释放锁
                lock.unlock();
            }
            }
    }
}
public class Test {
    public static void main(String[] args) {
        //建立MyThread对象
        MyThread mt = new MyThread();
        //建立三个窗口
        Thread t1 = new Thread(mt);
        Thread t2 = new Thread(mt);
        Thread t3 = new Thread(mt);
        //给每个窗口设置姓名
        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");
        //开启窗口进行售票
        t1.start();
        t2.start();
        t3.start();
    }
}

死锁问题:
同步嵌套,锁里面套了一个锁,出现同步嵌套多线程

package com.edu_14;
public class DieThread extends Thread{
    boolean flag;
    //提供一个有参构造
    public DieThread(boolean flag){
        this.flag = flag;
    }
    @Override
    public void run() {
        if (flag) {
            synchronized (MyLock.objA) {
                System.out.println("if"+"objA");
                synchronized (MyLock.objB) {
                    System.out.println("if"+"objB");
                }
            }
        }else {
            synchronized (MyLock.objB) {
                System.out.println("else"+"objB");
                synchronized (MyLock.objA) {
                    System.out.println("else"+"objA");
                }
            }
        }
    }
}
package com.edu_14;
public abstract class MyLock {
    //定义两个锁
    public static final Object objA = new Object();
    public static final Object objB = new Object();
}
package com.edu_14;
public class Test {
    public static void main(String[] args) {
        //建立两个线程,分别设置不一样的布尔值
        DieThread dt = new DieThread(true);
        DieThread dt2 = new DieThread(false);
        //开启两个线程
        dt.start();
        dt2.start();
    }
}

线程等待和唤醒机制:waitThread,NotifyThread,MyLock,Test
锁对象调用wait() 锁对象调用notify()ide

package com.edu_15;
public abstract class MyLock {
    public static final Object obj = new Object();
}
package com.edu_15;
public class WaitThread extends Thread{
    @Override
    public void run() {
        synchronized (MyLock.obj) {
            //让等待线程处于等待状态
            try {
                MyLock.obj.wait();//当线程处于等待状态的时候,线程就不会继续往下执行了
                                  //线程在处于等待的时候,会释放掉本身手中的锁
                                 //sleep()这个方法,在线程休息的时候会释放锁码?
                                //答:不会
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println("我被唤醒了");
    }
}
package com.edu_15;
public class NotifyThread extends Thread{
    @Override
    public void run() {
        synchronized (MyLock.obj) {
            //唤醒等待线程
            MyLock.obj.notify();//唤醒正在等待的线程,唤醒的等待线程的锁对象,必须和等待线程的锁对象一致
        }
    }
}
package com.edu_15;
/* (11)线程等待和唤醒机制(案例演示:waitThread,NotifyThread,MyLock,Test) 锁对象调用wait():线程的等待 锁对象调用notify():线程的唤醒 * 注意: wait和sleep的区别 线程等待,在等待的同时释放锁,而sleep()方法在执行的过程当中是不会释放锁的 */
public class Test {
    public static void main(String[] args) {
        //建立等待线程,让等待线程处于一个等待状态
        WaitThread wt = new WaitThread();
        wt.start();
        //睡上5秒钟以后唤醒等待线程
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //建立唤醒线程对象
        NotifyThread nt = new NotifyThread();
        nt.start();
    }
}

注意:wait和sleep的区别:
线程等待,在等待的同时释放锁,而sleep()方法在执行的过程当中是不会释放锁的
svg

Java多线程(一):
https://blog.csdn.net/Veer_c/article/details/103842078
Java多线程(二):
https://blog.csdn.net/Veer_c/article/details/103842263
Java多线程(三):
https://blog.csdn.net/Veer_c/article/details/103842317
Java多线程(四):
https://blog.csdn.net/Veer_c/article/details/103842602
this