同步

来源:互联网 发布:买淘宝号多少钱一个 编辑:程序博客网 时间:2024/04/28 10:34
同步(synchronized)
格式:
synchronized (对象)
{
     需要同步的代码;
}
同步可以解决安全问题的根本原因就在那个对象上。
该对象如同锁的功能。
案例:


public class TicketDemo {
    public static void main(String[] args) {
            Person2 p1 = new Person2("haoren");        Thread t1 = new Thread(p1);

        Thread t2 = new Thread(p1);

        t1.start();
                t2.start();


    }


}


class Person2 implements Runnable {    private String name;
        private int tickets = 5;


    public Person2(String name) {

        this.name = name;

    }
    Object object1 = new Object();
    public void run() {

            for (int i = 0; i < 5; i++) {

        synchronized (object1) {//object1就是传说中的锁,要同步必须使用同一个锁        if (tickets > 0) {

                    try {
                                                Thread.sleep(200);
                    } catch             (InterruptedException e) {

                                        e.printStackTrace();
                    }

                            System.out.println(tickets--);
                }
                        }
        
        }

    }

}同步的前提:
同步需要两个或者两个以上的线程。
多个线程使用的是同一个锁。
未满足这两个条件,不能称其为同步。
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

同步函数:
格式:在函数上加上synchronized修饰符即可。
同步函数的锁是this,而同步代码库的锁可以是任意对象
package cn.java.thread;

/*
 证明同步函数用的是this这把锁
 */
public class Tickets1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * GetTickets gt1 = new GetTickets(); GetTickets gt2 = new GetTickets();
         * GetTickets gt3 = new GetTickets(); gt1.setName("窗口一");
         * gt2.setName("窗口二"); gt3.setName("窗口三"); gt1.start(); gt2.start();
         * gt3.start();
         */
        GetTickets2 gt = new GetTickets2();
        Thread th1 = new Thread(gt, "窗口一");
        Thread th2 = new Thread(gt, "窗口二");
        Thread th3 = new Thread(gt, "窗口三");
        th1.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        gt.flag = true;
        th2.start();
        th3.start();
    }

}

class GetTickets2 implements Runnable {

    private int tickets = 10;
    boolean flag = false;
    Object ob = new Object();
    public void run() {
        if (flag) {
            for (int i = 0; i < 10; i++) {
                //synchronized (ob) {//如果用ob就无法同步
                synchronized (this) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                + "卖出" + (tickets--) + "号票"+":同步代码块");
                    }
                }
                
            }
            
        } else {
            for (int i = 0; i < 10; i++) {
                function();
                
            }

        }
    }

    public synchronized void function() {

        if (tickets > 0) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "卖出"
                    + (tickets--) + "号票"+":同步函数");
            
        }
    }

}
/*
 * class GetTickets extends Thread{ //private static int tickets = 10; private
 * int tickets = 10; public void run(){
 *
 * for (int i = 0; i < 10; i++) { if(tickets>0){
 * System.out.println(Thread.currentThread().getName()+"卖出"+(tickets--)+"号票"); }
 * } } }
 */


态同步函数的锁是本类的字节码对象:
    public void run() {
        if (flag) {
            for (int i = 0; i < 10; i++) {
                //synchronized (this.getClass()) {
                synchronized (GetTickets2.class) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                + "卖出" + (tickets--) + "号票"+":同步代码块");
                    }
                }
            }
            
        } else {
            for (int i = 0; i < 10; i++) {
                function();
                
            }
        }
    }
    public static synchronized void function() {

        if (tickets > 0) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "卖出"
                    + (tickets--) + "号票"+":同步函数");
            
        }
    }

0 0