1、什么是多线程之间的通讯?
多个线程对同一个资源(共享资源),每个线程对共享资源做的动作不同。操作不同。
多线程通讯的生产者与消费者。消息中间件。
如图
2、wait的作用?notify作用?
wait的作用: 是让当前线程从运行状态变为休眠状态,释放锁资源
notify: 是让当前线程从休眠状态变为运行状态。唤醒线程。
注意:wait和notify只有在同步的时候才能使用,如在synchronized代码块中使用,而且都是锁来调用的,并且用的是同一个锁。
3、多线程对共享资源写操作有安全问题,一读一写怎么会有安全问题?
解决方法:首先,两个线程都需要进行同步。
生产者线程生产一个,消费者立马消费,
生产者没有任何生产,消费者就不能做读操作。
消费者,没有消费完,生产者就不能继续生产。
这里就是要使用 wait 方法和notify方法。
注意:可见性不具备原子性,线程不安全。
图示
4、多线程之间实现同步或通讯的话使用什么?
使用synchronized 和wait 来实现,wait和notify是一起用的,
notifyAll()是唤醒所有等待的线程。
wait 和 notify只能在synchronized中使用才能有通讯功能。
5、sleep和wait的区别?
wait: 是用于同步中可以释放锁的资源,wait需要notify才能从休眠状态变成运行状态。
sleep: 不会释放锁的资源。时间到期从休眠状态变为运行状态。
相同点都是:休眠线程。
以上记录Java多线程之间的通讯基础基本完毕
6、synchronized分析
synchronized(res){
}
Synchronized:什么时候上锁? 答:在代码块开始上锁
synchronized:什么时候释放锁? 答:在代码块结束
synchronized称为内置锁,自动化。
缺点:效率低、扩展不高,不能自定义。
7、JDK1.5 并非包里面的lock锁
并发包:3-5年面试问
并发包里面的Lock锁,保证线程安全问题。
lock锁与synchronized同步锁,有什么区别?
lock:手动上锁,手动释放锁,灵活性高。
多线程并发与网站并发?
多线程并发操作同一个资源
网站并发,多个请求操作同一个资源。
8、lock锁是接口和synchronized关键字区别?
lock锁:可以尝试非阻塞地获取锁,当前线程尝试获取锁,如果这一时刻没有呗其他线程
获取到,则成功获取并持有锁。
lock锁:能被中断的获取锁,与synchronized不用,获取到锁的线程能够享有中断。
当获取到的锁的线程被中断时,中断异常就会被抛出,同时锁会呗释放。
lock锁:能在制定的截止时间获取锁,如果截止时间到了依旧无法获取锁则返回。
lock锁要自己去释放锁,synchronized程序执行完毕就会释放锁,或者程序抛出异常锁也会被释
放。
9、停止线程的方法
第一种:使用标识符来结束线程,标识符必须要使用可见性,使用volatile修饰。
代码:
package com.leeue.mykt;
/**
*
* @classDesc: 功能描述:(停止线程第一种方法 使用volatie)
* @author:李月
* @Version:v1.0
* @createTime:@Date 2018年7月8日 下午11:12:38
*
*/
class StopThreadDemo extends Thread{
private volatile boolean flag = true;
@Override
public void run() {
System.out.println("子线程开始执行...");
while(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("子线程结束执行...");
}
public void stopThread(){
System.out.println("调用了stopThread()方法");
flag = false;
System.out.println("已经讲flag修改为"+flag);
}
}
public class StopThread {
public static void main(String[] args) throws InterruptedException{
StopThreadDemo threadDemo = new StopThreadDemo();
Thread thread = new Thread(threadDemo);
thread.start();//启动线程
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
if(i==3){
//threadDemo.interrupt();//表示让当前等待的线程抛出异常
threadDemo.stopThread();
}
}
}
}
第二种方法就是让异常抛出
9、什么是ThreadLocal?
1、什么是ThreadLocal?
答:为每一个线程提供一个局部变量。
不使用ThreadLocal来实现为每个线程提供一个局部变量的方法:
package com.leeue.mykt;
/**
*
* @classDesc: 功能描述:(ThreadLock 本地线程)
* @author:李月
* @Version:v1.0
* @createTime:@Date 2018年7月11日 上午10:50:00
*
*/
class ResNumber{
public int count = 0;
public String getNumber(){
count = count + 1;
return count + "";
}
}
class LocaThreadDemo extends Thread{
private ResNumber resNumber;
public LocaThreadDemo(ResNumber resNumber){
this.resNumber = resNumber;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(getName()+","+resNumber.getNumber());
}
}
}
public class ThreadLockDemo {
public static void main(String[] args) {
ResNumber resNumber1 = new ResNumber();
ResNumber resNumber2 = new ResNumber();
ResNumber resNumber3 = new ResNumber();
LocaThreadDemo t1 = new LocaThreadDemo(resNumber1);//同时共享数据
LocaThreadDemo t2 = new LocaThreadDemo(resNumber2);
LocaThreadDemo t3 = new LocaThreadDemo(resNumber3);
t1.start();
t2.start();
t3.start();
}
}
使用ThreadLocal方式给每个线程创建一个属于自己的局部变量的代码
package com.leeue.mykt;
import java.util.concurrent.CountDownLatch;
/**
*
* @classDesc: 功能描述:(ThreadLock 本地线程)
* @author:李月
* @Version:v1.0
* @createTime:@Date 2018年7月11日 上午10:50:00
*
*/
class ResNumber{
public int count = 0;
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
protected Integer initialValue() {//注意这里
return 0;
}
};//类的初始化可以这样初始化
public String getNumber(){
count = threadLocal.get() + 1;
threadLocal.set(count);//还要把当前的值赋值进去
return count + "";
}
}
class LocaThreadDemo extends Thread{
private ResNumber resNumber;
public LocaThreadDemo(ResNumber resNumber){
this.resNumber = resNumber;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(getName()+","+resNumber.getNumber());
}
}
}
public class ThreadLockDemo {
public static void main(String[] args) {
ResNumber resNumber = new ResNumber();
LocaThreadDemo t1 = new LocaThreadDemo(resNumber);//同时共享数据
LocaThreadDemo t2 = new LocaThreadDemo(resNumber);
LocaThreadDemo t3 = new LocaThreadDemo(resNumber);
t1.start();
t2.start();
t3.start();
}
}
ThreadLocalThreadLoca通过map集合
Map.put(“当前线程”,值);