Init.Sun Chengdu.Sichuan

java多线程笔记

2018-06-15
Init

java多线程笔记01

普通方式加锁 synchronized

多线程判断用while,否则有虚假唤醒的问题


// 普通方式加锁 synchronized

public synchronized void increment(){
    String threadName = Thread.currentThread().getName();
    while (number !=0){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    ++number;
    System.out.println(threadName + "-->" + number);
    // 通知
    this.notifyAll();
}

public synchronized void decrement(){
    String threadName = Thread.currentThread().getName();
    while (number == 0){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    --number;
    System.out.println(threadName + "-->" + number);
    // 通知
    this.notifyAll();

}

ReentrantLock 锁


//ReentrantLock 锁 -- 他还有读写锁,读可以所有的读,写只能一个写(互斥)
package com.cdinit;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ShareData {
    private int number = 0;

    private Lock lock = new ReentrantLock(); // 1.new ReentrantLock

    private Condition condition = lock.newCondition(); // 2. 获取newCondition

    public void increment() {
        String threadName = Thread.currentThread().getName();
//        System.out.println("Increment Thread --> " + Thread.currentThread().getName());
        lock.lock(); // 3.lock
        try{
            while (number != 0){
                try {
                    condition.await(); // 注意是await
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            ++number;
            System.out.println(threadName + " increment-->" + number);
            // 通知 必须获得锁
            condition.signalAll();
        }finally {
            lock.unlock();
        }

    }

    public void decrement() {
        String threadName = Thread.currentThread().getName();
//        System.out.println("Decrement Thread --> " + Thread.currentThread().getName());
        lock.lock();
        try{
            while (number == 0){
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            --number;
            System.out.println(threadName + " Decrement-->" + number);
            // 通知 必须获得锁
            condition.signalAll();
        }finally {
            lock.unlock();
        }
    }
}

package com.cdinit;

public class ApplicationMain {

	public static void main(String[] args) {

        ShareData shareData = new ShareData();
        new Thread(() -> {
            for(int i=0;i<100;i++){
                shareData.decrement();
            }
        },"T1").start();

        new Thread(() -> {
            for(int i=0;i<100;i++){
                shareData.increment();
            }
        },"T2").start();
        new Thread(() -> {
            for(int i=0;i<100;i++){
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                shareData.decrement();
            }
        },"T3").start();

        new Thread(() -> {
            for(int i=0;i<100;i++){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                shareData.increment();
            }
        },"T4").start();
	}

}

锁静态方法就是锁.class ,锁普通方法是锁this


package com.cdinit;

import java.util.concurrent.TimeUnit;

class Phone {
    public synchronized void sendSMS() throws Exception{
        TimeUnit.SECONDS.sleep(2);
        System.out.println("...sendSMS");
    }
    public synchronized void sendEmail() throws Exception{
        System.out.println("...sendEmail");
    }
    public void openPad(){
        System.out.println("...openPad");
    }
    public static void sendStaticsendSMS() throws Exception{
        System.out.println("...sendStaticSMS");
    }
    public static void sendStaticsendEmail() throws Exception{
        TimeUnit.SECONDS.sleep(4);
        System.out.println("...sendStaticEmail");
    }

}

class Lock_B{
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();

        new Thread(()->{
            try {
                phone.openPad();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(()->{
            try {
                Phone.sendStaticsendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(()->{
            try {
                Phone.sendStaticsendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"C").start();
    }
}

ReentrantLock可以做线程调度

package com.cdinit;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


class ShareDataSource{
    private int number = 1;
    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    public void print5(int totalLoop) throws InterruptedException {
        lock.lock();
        try{
            //1 判读
            while (number != 1){
                c1.await();
            }
            //2 干活
            for(int i=1;i<=5;i++){
                System.out.println(Thread.currentThread().getName() + "-->" + i +", total--> "+ totalLoop);
            }
            //3 通知
            number = 2;
            c2.signal();
        }finally {
            lock.unlock();
        }
    }

    public void print10(int totalLoop) throws InterruptedException {
        lock.lock();
        try{
            //1 判读
            while (number != 2){
                c2.await();
            }
            //2 干活
            for(int i=1;i<=10;i++){
                System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
            }
            //3 通知
            number = 3;
            c3.signal();
        }finally {
            lock.unlock();
        }
    }

    public void print15(int totalLoop) throws InterruptedException {
        lock.lock();
        try{
            //1 判读
            while (number != 3){
                c3.await();
            }
            //2 干活
            for(int i=1;i<=15;i++){
                System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
            }
            //3 通知
            number = 1;
            c1.signal();
        }finally {
            lock.unlock();
        }
    }

}

public class SeqThread {
    public static void main(String args[]) throws Exception{
        ShareDataSource shareDataSource = new ShareDataSource();
        new Thread(()->{
            for(int i=0;i<10;i++){
                try {
                    shareDataSource.print5(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();

        new Thread(()->{
            for(int i=0;i<10;i++){
                try {
                    shareDataSource.print10(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();

        new Thread(()->{
            for(int i=0;i<10;i++){
                try {
                    shareDataSource.print15(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"CC").start();
    }
}


Similar Posts

Comments