Java多线程

9 篇文章 0 订阅
2 篇文章 0 订阅
1. 进程与线程区别

线程是进程中独立运行的子任务。协程,coroutine,又称微线程。协程看上去也是子程序,但是内部可以中断,转而执行别到子程序。不需要切换线程上下文。
停止线程:Thread.stop()已被弃用,大多数停止一个线程使用到方法是Thread.interrupt()方法,这个方法不会中止一个正在运行的线程,还需要加入一个判断才可以完成线程的中止。
this.interrupted():测试当前线程是否已经是中断状态,执行后会清除状态。
this.isInterrupted():测试当前线程是否已经是中断状态,不清除状态。
怎么停止线程? 可以在代码中判断当前线程是否被中断,如果被中断,停止操作。
还可以使用suspend()挂起,来暂停线程,使用resume()来恢复线程执行。
yield()方法放弃CPU,但是时间不确定,可能刚放弃就又获得。

2. 并发访问

”非线程安全“问题存在于”实例变量“中,如果是方法内部到私有变量,则不存在”非线程安全“问题。
synchronized锁可重入,也就是说当一个线程获取到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。为什么可重入,对象持有锁后,还没释放时,如果想再次获取锁,如果不可重入,就会发生死锁
死锁是必须要避免到,因为会造成线程假死。

3. volatile关键字

主要作用是使变量在多个线程间可见。(每次读取变量从主内存中读取),其致命缺点在于不支持原子性,因而会造成”线程不安全“。而synchronized保证了原子性。同步状态下的变量从读到操作到存入主内存,必须在一个同步代码段执行完;而volatile只能保证每次读是从主内存读,但是读的同时可能另一个线程在操作,还未写入。
主要作用在于变量到变化能被读取到。

4. 线程间通信
4.1 等待/通知机制

实现是在Object类中。
wait()方法的作用是使当前执行代码的线程进行等待,直到接到通知或被中断为止。notify()方法在调用前,必须获得该对象的锁,然后对一个处于wait状态的线程发出通知,**使他等待获取该对象锁。**在执行notify()方法后,不会马上释放该对象锁,要等到该线程执行完后,退出同步代码块后,才会释放锁。如果对象锁释放,但是没有notify,其他wait状态的线程还会继续wait阻塞,直到有notify、通知。
这两个方法必须在同步代码块中执行。

4.2 通过管道进行线程间通信

pipeStream是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读取数据。两个线程之间到通信。
join方法阻塞当前线程,执行新线程。

4.3 ThreadLocal

不同线程拥有自己的值。

5. Lock

JUC中的ReentrantLock也能达到synchronized效果,功能更强大。
使用栗子:

public class MyService {
    private Lock lock = new ReentrantLock();
    public void testMethod() {
        lock.lock();
        for (int i = 0; i < 5; ++i) {
            System.out.println("name " + Thread.currentThread().getName() + ": " + i);
        }
        lock.unlock();
    }
}

使用Condition实现等待/通知。使用ReentrantLock也可以实现等待通知模式,但要借助Condition对象。

public class MyService {
    private Lock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();

    public void await() {
        try {
            lock.lock();
            System.out.println("await time = " + System.currentTimeMillis());
            condition.await();
        }catch (InterruptedException ex) {
            ex.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void signal() {
        try {
            lock.lock();
            System.out.println("signal time = " + System.currentTimeMillis());
            condition.signal();
        }finally {
            lock.unlock();
        }
    }
}
6. 定时器Timer

Timer类到主要作用就是设置计划任务,当封装任务到类却是TimerTask类。

7. 单例模式
7.1 双检锁
public class MyObject {
    private volatile static MyObject myObject;
    private MyObject() {

    }
    public static MyObject getInstance() {
        try {
            // 准备工作
            Thread.sleep(1000);
            if (myObject == null) {
                synchronized (MyObject.class) {
                    if (myObject == null){
                        myObject = new MyObject();
                    }
                }
            }
        }catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        return myObject;
    }
}
7.2 静态内部类
public class MyObject {
    private static class MyObjectHandler {
        private static MyObject myObject = new MyObject();
    }
    private MyObject() {

    }
    public static MyObject getInstance() {
        return MyObjectHandler.myObject;
    }
}
7.3 static代码块
public class MyObject {
    private static MyObject myObject = null;
    private MyObject() {

    }
    static {
        myObject = new MyObject();
    }
    public static MyObject getInstance() {
        return myObject;
    }
}
7.4 枚举类
public enum  MyObject {
    INSTANCE;
    public void tellEveryone(){
        System.out.println(this.hashCode());
    }
}

但是JUC才是java多线程到重点,后面再写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值