Java 多线程

这里就只浅显的记录一下多线程,不去深究啥对象头、AQS。。。

synchronized

  Java关键字synchronized有两种使用方式:①synchronized方法②synchronized块。

1. synchronized方法
  synchronized方法就是在方法名前面添加synchronized关键字。

class PrintStr {
    synchronized void printA() {}
}

  使用这种方式进行同步,锁的是syn方法所在的对象的临界资源。

2. synchronized块
  synchronized块是一种比较灵活的方式。使用时需要传入一个对象:

Object o = new Object();
synchronized(o){
	o.notify();
	o.wait();
}

这个时候锁的就是o这个对象了,notify和wait的用法和ReentrantLock的差不多。看下面。

ReentrantLock

一般来说使用重入锁会用到reentrantLock.lockreentrantLock.unlockCondition.await()Condition.signal()Condition.signalAll()

咋用呢?
一般要把ReentrantLock实例化,得到一个重入锁对象 relock。

ReentrantLock relock = new reentrantLock();

  刚开始,relock的锁的状态是free的。当有线程1来调用relock.lock()时,会继续往下执行下去,并且获得relock对象的锁。
  当线程2来获取锁的时候(调用relock.lock()),是获取不到锁的,线程2或卡在relock.lock();这一行代码。只有当线程1执行relock.unlock()的时候,线程1释放了锁,线程2就会获得锁,并继续执行下去。
当有n个线程来的时候,一个线程释放锁,其余线程谁来获得锁的问题就先暂时不说了(AQS技术)。


下面来讲讲重入锁的精髓 》》Condition《《
(个人理解,谨慎参考)

  Condition是用来做线程交替进行的机制。

Condition c = relock.newCondition();

  当一个线程在获得锁期间使用了c.await(),这个线程将卡在c.await()这个方法。同时,这个线程将处于一个等待(无锁)的状态。其他的线程可以获得锁(relock.lock())执行代码。只有当另一个线程调用了c.signal()方法时,原先的线程才能醒来,进入“就绪状态”,等待调用了signal的方法执行await()来释放锁,原先的线程获得锁后await()方法才能继续执行下去。
  所以signalsignalAll的区别在哪?
  假如多个线程都执行了c.await(),某个线程执行了c.signal(),那么排队的线程会有一个能继续执行await()方法往下走。要是执行的c.signalAll(),那么排队线程都能够继续执行await()方法向下走。注意c对象得是同一个。比如c1.signal()只能唤醒c1.await(),不能唤醒c2.await()。

下面来举个栗子:新建两个线程,使他们交替执行,打印出12A 34B 56C …4950 y 5152z

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

public class ThreadNumChar2 {
    public static void main(String[] args) throws InterruptedException {
        ReentrantLock relock = new ReentrantLock();
        Condition c1 = relock.newCondition();
        Condition c2 = relock.newCondition();

        new Thread(new Runnable() { //数字线程
            @Override
            public void run() {
                try{
                    relock.lock();
                    for (int i = 1; i < 53; i++) {
                        System.out.print(i);
                        if(i % 2 == 0){
                            c1.signal(); //使得c1.await()方法能够往下执行
                            c2.await(); //释放锁,进入睡眠“就绪”状态
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    relock.unlock();
                }
            }
        }).start(); //开启线程

        Thread.sleep(2); //使得第二个线程能慢2ms执行,保证数字线程先输出
        new Thread(new Runnable() { // 字母线程
            @Override
            public void run() {
                try{
                    relock.lock();
                    for (int i = 1; i <= 26; i++) {
                        System.out.println((char)('A'-1+i));
                        c2.signal(); // 使c2.await()方法能够向下执行
                        if(i != 26){
                            c1.await(); //释放字母线程的锁,进入等待状态
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    relock.unlock();
                }
            }
        }).start(); //开启线程
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值