线程小结二

线程小结二

一、线程休眠

使用静态方法sleep(long millis)可以让当前进程暂停一段时间,进入休眠等待状态,实现人为的控制线程。


二、线程让步

通过yield()方法实现

yield()和sleep()的区别:yield()不会阻塞该线程,只是将线程转换成就绪状态,让线程的调度器重新调度一次。


三、线程插队

通过join()方法来完成

当在某个线程中调用其它线程的join()方法时,调用的线程将被阻塞,直到被join()加入的线程执行完成后才会继续执行


多线程同步

一、线程安全性

一个类是线程安全的,是指在被多个线程访问时,类是可以持续进行正确的行为。

线程安全问题就是由多个线程同时处理共享资源所导致的


二、同步代码块

当多个线程使用同一个共享资源时,可以将处理共享资源的代码放置到一个代码块中,使用sychronized关键字来修饰,被称作同步代码块

synchronized(lock){
操作共享资源代码块
}


lock是一个锁对象,当线程执行同步代码块时,首先会检查锁对象的标志位,默认情况下为1,此时线程会执行同步代码块,并将锁对象的标志位置0。这时当一个新的线程执行到 这段同步代码块时,由于锁对象的标志位为0,新线程会发生阻塞,等待当前线程执行完同步代码块后,锁对象的标志位被置为1,新线程才能进入其中并执行。

注意:同步代码块中的锁对象可以是任意类型的对象   ,但多个线程共享的锁对象必须是唯一的。“任意”说的是共享锁对象的类型。所以,锁对象的创建代码不能放到run()方法中,否则每个线程运行到run()方法都会创建一个新对象,这样每个线程都会有一个不同的锁,每个锁都有自己的标志位。


三、同步方法

 在方法前加入synchronized修饰,被称为同步方法。此方法在某一时刻只允许一个线程访问,访问该方法的其他线程都会发生阻塞。

同步代码块的锁是自定义的任意类型的对象

同步方法的锁就是当前调用该方法的对象,就是this指向的对象。如果需要同步的方法是静态方法,这时会有疑问,静态方法不需要创建对象就可以直接用“类名.方法名()”方式来调用。如果不创建对象,静态同步方法的锁就不会是this,那么静态同步方法的锁是什么呢?java中静态方法的锁是该方法所在类的class对象,该对象可以直接用“类名.class” 的方式获取


同步代码块和同步方法解决多线程问题的优点:解决了多个线程同步时访问共享数据时的线程安全问题,只要加上同一个锁,在同一时间内只能有一条线程执行。

缺点:每次都会判断锁的状态,非常消耗资源,效率低下


四、死锁问题

两个线程都在等待对方的锁,便造成了程序的停滞,这种现象称为死锁。


多线程通信

解决这个多线程通信问题,需要控制多个线程按照一定的顺序轮流执行。Object类提供了wait()、notify()、notifyAll()方法用于解决线程间通信问题。

wait()使当前线程进入等待状态,notifu()和notifyAll()用于唤醒当前处于等待状态的线程。这三个方法的调用者都应该是同步锁对象,若不是JVM会抛出IllegalMonitorStateException异常                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   


Java多线程是指在一个Java程序中同时执行多个线程,每个线程都是独立的执行流。Java中创建线程的方式有三种:继承Thread类、实现Runnable接口和实现Callable接口。每种方式都有其优缺点。 1. 继承Thread类创建线程类: ```java class MyThread extends Thread { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 MyThread thread = new MyThread(); thread.start(); ``` 优点:简单易用,可以直接重写Thread类的run()方法。 缺点:由于Java不支持多继承,继承了Thread类就无法再继承其他类。 2. 实现Runnable接口创建线程类: ```java class MyRunnable implements Runnable { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 Thread thread = new Thread(new MyRunnable()); thread.start(); ``` 优点:避免了单继承的限制,可以继续继承其他类或实现其他接口。 缺点:需要额外创建Thread对象,并将Runnable对象作为参数传递给Thread对象。 3. 实现Callable接口创建线程类: ```java class MyCallable implements Callable<Integer> { public Integer call() throws Exception { // 线程执行的代码 return 0; } } // 创建线程对象 ExecutorService executor = Executors.newFixedThreadPool(1); // 提交Callable任务并获取Future对象 Future<Integer> future = executor.submit(new MyCallable()); // 获取线程执行结果 int result = future.get(); ``` 优点:可以获取线程执行的结果,并且可以抛出异常。 缺点:相对于前两种方式,使用Callable需要更多的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值