JAVA笔记14__多线程共享数据(同步)/ 线程死锁 /

/**
 * 多线程共享数据
 * 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行。
 * 多线程共享数据的安全问题,使用同步解决。
 * 线程同步两种方法:
 * 1.同步代码块
 *      synchronized(要同步的对象){ 要同步的操作 }
 * 2.同步方法
 *      public synchronized void method(){ 要同步的操作 }
 */
public class Main {
    public static void main(String[] args) {
        MyThread s0 = new MyThread();
        Thread t1 = new Thread(s0,"one");
        Thread t2 = new Thread(s0,"two");
        t1.start();
        t2.start();
    }
}

class MyThread implements Runnable{
    Object obj = new Object(); //同步的标记对象
    @Override
    public void run() {
        //同步代码块
        synchronized(obj){
            System.out.println(Thread.currentThread().getName()+" is doing...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" finished.");
        }
    }
}

 

public class Main {
    public static void main(String[] args) {
        MyThread s0 = new MyThread();
        Thread t1 = new Thread(s0,"one");
        Thread t2 = new Thread(s0,"two");
        t1.start();
        t2.start();
    }
}

class MyThread implements Runnable{
    @Override
    public void run() {
        doMethod();
    }
    /**
     * 同步方法,同步的是当前对象(this)
     */
    public synchronized void doMethod(){
        System.out.println(Thread.currentThread().getName()+" is doing...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" finished.");
    }
}

/**
 * 同步代码会带来性能降低的问题,担高数据的安全性
 * 当编写synchronized块时,有几个简单准则可以遵循。
 * 1.使代码块保持简短,把不随线程变化的预处理和后处理移出synchronized块。
 * 2.不要阻塞。如InputStream.read()。
 * 3.在持有锁的时候,不要对其它对象调用方法。
 */

 

/**
 * 线程死锁:同步过多,会造成死锁
 */
public class Main {
    public static void main(String[] args) {
        new MyThread();
    }
}

class MyThread implements Runnable{
    Customer c = new Customer();
    Waiter w = new Waiter();
    public MyThread(){
        new Thread(this).start();
        w.say(c);
    }
    @Override
    public void run() {
        c.say(w);
    }
}

class Customer{ //顾客
    public synchronized void say(Waiter w){
        System.out.println("顾客说:先做再给钱!");
        w.doService();
    }
    public synchronized void doService(){
        System.out.println("顾客同意了,先给钱再做");
    }
}
class Waiter{ //服务员
    public synchronized void say(Customer c){
        System.out.println("服务员说:先给钱再做!");
        c.doService();
    }
    public synchronized void doService(){
        System.out.println("服务员同意了,先做再给钱");
    }
}
//Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
//1.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
//2.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
//3.尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
//4.第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
//5.以上规则对其它对象锁同样适用。

 


 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。