Java线程同步锁

把synchronized当作函数修饰符时,示例代码如下:

  

Public synchronized void method(){
//….
}  

  这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。

  如同这样

public void method()
{
synchronized (this)      //  (1)
{
       //…..
}
}   

  此处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。具体使用像这样:

  

package com.java.Thread;

public class Mysynchronized {
    /**
     * @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--)+"号票"); }
 * } } }
 */

  将synchronized作用于static 函数 同步的锁就是它自己本身的字节码,示例代码如下:

     Class Foo
{
public synchronized static void method1()   // 同步的static 函数
{
//….
}
public void method2()
{
       synchronized(Foo.class)   //  class literal(类名称字面常量)
}
       }   

具体代码如下

Java线程同步锁
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 static int tickets = 10;
boolean flag = false;
Object ob = new Object();
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--) + "号票"+":同步函数");

}
}

}
/*
* 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--)+"号票"); }
* } } }
*/

然后嘞是 wait notify notifyall 这三个(两个)方法的 理解了 第一步 wait的作用是阻塞 notify的作用是唤醒

  讲这个 要用到以前学到的生产者和消费者 对于他们的理解:

  1.这些方法都存在与同步中

  2;使用这些方法时必须要标记所属的同步锁

  3:锁可以是任意对象,所以任意对象调用的方法一定定义在object类中  废话不多上代码:

  这是同步代码块的

package com.java.Thread;
//定义一个rbq
class Production{
    private String name;
    private String country;
    private boolean flag = true;
    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

}
class Producer implements Runnable{
    private Production p = null;

    public Producer(Production p) {
        this.p = p;
    }
    public void run(){
        boolean b = true;
        while(true){
            synchronized (p) {
                if(p.isFlag()){
                    //这个b就是打酱油的
                    if(b){
                        p.setName("李小文院士");
                        p.setCountry("中国");
                        b = false;
                    }
                    else{
                        p.setName("加来道雄博士");
                        p.setCountry("日本");
                        b = true;
                    }
                    //唤醒 并且这里注意 把flag改变成了 false
                    p.setFlag(false);
                    p.notify();
                }
                else
                    try {
                    //老样子 否则就过来阻塞
                        p.wait();
                    } catch (Exception e) {
                        // TODO: handle exception
                    }

            }

        }
    }

}
class Saler implements Runnable{
    private Production p = null;
        //表明同步的锁!!!!
    public Saler(Production p) {
        this.p = p;
    }

    public void run() {
        while(true){
            synchronized (p) {
                //上面的 isFlage被设定成 false了 所以这里要不等于 然后他们 就这样一直轮回下去 下面没了就让上面造
                if(!p.isFlag()){
                    //获取前面的 赋值
                    System.out.println(p.getName()+":"+p.getCountry());
                    p.setFlag(true);
                    //唤醒 动起来
                    p.notify();
                }
                else{
                    try {
                        //阻塞
                        p.wait();
                    } catch (Exception e) {
                        // TODO: handle exception
                    }

                }

            }

        }

    }

}

public class ProductionDemo{
public static void main(String[] args) {
        Production p = new Production();
        Producer producer = new Producer(p);
        Saler saler = new Saler(p);
        Thread th1 = new Thread(producer);
        Thread th2 = new Thread(saler);
        th1.start();
        th2.start();

        }
        }

小钢炮这个是同步函数的

public class ProductionDemo{
public static void main(String[] args) {
        // 这是同步函数的
       /* Production p = new Production();
        Producer producer = new Producer(p);
        Saler saler = new Saler(p);
        Thread th1 = new Thread(producer);
        Thread th2 = new Thread(saler);
        th1.start();
        th2.start();
        */
        //同步代码块
    Production p = new Production();
    Producer pd = new Producer(p);
    Saler s = new Saler(p);
    Thread th1 = new Thread(pd);
    Thread th2 = new Thread(s);
    th1.start();
    th2.start();

}
}

//同步代码块
class Production {
    private String name;
    private int num = 0;
    private boolean b = false;

    public boolean isB() {
        return b;
    }

    public void setB(boolean b) {
        this.b = b;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

}

class Producer implements Runnable {

    private Production p = null;

    public Producer(Production p) {
        this.p = p;
    }

    public void run() {
        while (true) {
            synchronized (p) {
                if (p.isB()) {
                    try {
                        p.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                p.setName("小钢炮");
                p.setNum(p.getNum() + 1);
                System.out.println("生产:" + p.getName() + p.getNum());
                p.setB(true);
                p.notify();

            }

        }

    }

}

class Saler implements Runnable {

    private Production p = null;
    //获取定义的锁要一样
    public Saler(Production p) {
        this.p = p;
    }

    public void run() {
        while (true) {
            synchronized (p) {
                if (!p.isB()) {
                    try {
                        //阻塞
                        p.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("卖:" + p.getName() + p.getNum());
                p.setB(false);
                //唤醒
                p.notify();
            }
        }
    }

}

然后了是多生产者和多消费者 嘿嘿上码:

package cn.java.thread1;

public class ProductionDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Production2 p = new Production2();
        Producer2 pd = new Producer2(p);
        Saler2 s = new Saler2(p);
        Thread th1 = new Thread(pd);
        Thread th2 = new Thread(pd);
        Thread th3 = new Thread(s);
        Thread th4 = new Thread(s);
        Thread th5 = new Thread(pd);
        Thread th6 = new Thread(s);
        th1.start();
        th2.start();
        th3.start();
        th4.start();
        th5.start();
        th6.start();

    }

}

class Production2 {
    private String name;
    private int num = 0;
    private boolean b = false;

    public boolean isB() {
        return b;
    }

    public void setB(boolean b) {
        this.b = b;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public synchronized void produce() {
        //if (b) {
        while (b) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        setName("小钢炮");
        setNum(getNum() + 1);
        System.out.println("生产:" + getName() + getNum());
        setB(true);
        //notify();
        notifyAll();
    }

    public synchronized void sale() {
        //if (!b) {
        while(!b){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        System.out.println("卖:" + getName() + getNum());
        setB(false);
        //notify();
        notifyAll();

    }
}

class Producer2 implements Runnable {

    private Production2 p = null;

    public Producer2(Production2 p2) {
        this.p = p2;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            p.produce();

        }

    }

}

class Saler2 implements Runnable {

    private Production2 p = null;

    public Saler2(Production2 p2) {
        this.p = p2;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            p.sale();
        }

    }

}
上一篇:新型Web劫持技术


下一篇:向vsftp服务器上传文件报“550 Permission denied”错误的解决办法