1.死锁问题
1.1死锁
1.多线程出现安全问题可以使用同步方法或者同步代码块以及Lock解决安全问题,但是有可能出现死锁
2.死锁:当前多个线程操作不是同一个子类对象,可能会造成线程互相等待情况
解决方法:使用生产者和消费者模式
1.2 生产者消费者模式思路以及实现代码
1.SetThread类-->生产者所在线程资源类
GetThread类-->消费者所在线程资源类
Student类-->生产者线程不断产生学生数据,消费者线程不断使用学生数据
StudentTest-->主线程
2.
public class Student{
private String name;
private int age;
private boolean flag;
public synchronized void set(String name,int age){
if(this.flag){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.name = name;
this.age = age;
this.flag = true;
this.notify();
}
public synchronized void get(){
if(!this.flag){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
sout(this.name);
sout(this.age);
this.flag = false;
this.notify();
}
}
public class SetThread implements Runnable{
private Student s;
public SetThread(Student s){
this.s = s;
}
int x = 0;
public void run(){
while(true){
if(x % 2 == 0){
s.set("高圆圆",42);
}else{
s.set("赵又廷",45);
}
x++;
}
}
}
public class GetThread implements Runnable{
private Student s;
public GetThread(Student s){
this.s = s;
}
public void run(){
while(true){
s.get();
}
}
}
public class StudentTest{
public static void main(String[] args){
Student s = new Student();
SetThread st = new SetThread(s) ;
GetThread gt = new GetThread(s) ;
Thread t1 = new Thread(st) ;
Thread t2 = new Thread(gt) ;
t1.start() ;
t2.start() ;
}
}
2.线程池
1.线程池:创建一个固定的可重用的线程的数量
2.(1)JDK提供了一个工厂类:Executors
静态方法:public static ExecutorService newFixedThreadPool(int nThreads):建一个线程池,该线程池重用固定数量的线程
(2)JDK提供了一个接口:ExecutorService:线程池
<T> Future<T> submit(Callable<T> task):提供异步任务计算的结果
Future是接口,异步任务计算的结果
(3)void shutdown():启动有序关闭
(4)V get():获取计算结果
2.1创建线程池代码实现
1.
public class MyCallable implements Callable<>{
public Object call() throws Execption{
for(int i=0;i<100;i++){
sout(Thread.currentThread().getName()+":"+i);
}
return null;
}
}
public class Demo{
public static void main(String[] args){
ExecutorService threadPoll = Executors.newFixedThreadPool(2);
threadPoll.submit(new MyCallable());
threadPoll.submit(new MyCallable());
threadPoll.shutdown();
}
}
2.
需求:
使用线程池创建两个线程,然后分别计算求和
一个线程:1-100之间的和
另一个线程:1-200之间的和
public class MyCallable implements Callable<Integer>{
private Integer num;
public MyCallable(Integer num){
this.num = num;
}
public Integer call() throws Execption{
int sum = 0;
for(int x = 1 ; x <=num ; x++){
sum += x ;
}
return sum;
}
}
public class Demo{
public static void main(String[] args) throws
ExecutionException, InterruptedException{
ExecutionService threadPool = Executors.newFixedThreadPoll(2);
Future<Integer> f1 = threadPool.submit(new MyCallable(100));
Future<Integer> f2 = threadPool.submit(new MyCallable(200));
Integer i1 = f1.get();
Integer i2 = f2.get();
sout(i1);
sout(i2);
threadPool.shutdown();
}
}
2.2 面试题
1.线程池的优化
线程池的参数
public static ExecutorService newFixedThreadPoll(int nThreads){
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());)
}
2.ThreadPoolExecutor的构造方法之一:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
3.成员变量:
private final ReentrantLock mainLock = new ReentrantLock();
private volatile int corePoolSize;
private volatile int maximumPoolSize;
private volatile RejectedExecutiongHandler handler;
private volatile long keepAliveTime;
private volatile ThreadFactory threadFactoy;
private final BlockingQueue<Runnable> workQueue;
2.3 java的同步机制
synchronized同步代码块/同步方法
变量上面加入volatile
等待唤醒机制wait()和notify()
都可解决线程安全问题