java多线程与并发(上集)
一、Thread中的start和run方法的区别
1)调用start()方法会创建一个新的子线程并启动
2)run()方法只是Thread的一个普通方法的调用
二、Thread和Runnable是什么关系
1)Thread是实现了Runnable接口的类,使得run支持多线程
2)因类的单一继承原则,推荐多使用Runnable接口
三、如何给run()方法传参
1)构造函数传参
2)成员变量传参
3)回调函数传参
四、如何实现处理线程的返回值
1)主线程等待法
2) 使用Thread类的join()阻塞当前线程以等待子线程处理完毕
3)通过Callable接口实现:通过FutureTask Or线程池获取,如代码:
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public String call() throws Exception {
String value = "test";
System.out.println("ready to work");
Thread.sleep(5000);
return value;
}
}
使用FutureTask的demo
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskDemo {
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<String>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
if (!futureTask.isDone()){
System.out.println("please wait a minute");
}
try {
System.out.println("the result :" + futureTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
使用线程池demo
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExecutorPoolDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> future = executorService.submit(new MyCallable());
if (!future.isDone()){
System.out.println("task has not finished,please wait!");
}
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}finally {
executorService.shutdown();
}
}
}
五、线程的六个状态
线程的六个状态可在Thread的枚举类中找到,如代码:
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
如图中解释:
六、sleep和wait的区别
1)基本的差别
①sleep是Thread类的方法,wait是Object类中定义的方法
②sleep()方法可以在任何地方使用
③wait()方法只能在synchronized方法或synchronized块中使用
2)最主要的本质区别
①Thread.sleep只会让出CPU,不会导致锁行为的改变
②Object.wait不仅让出CPU,还会释放已经占有的同步资源锁七、notify和notify All区别
要了解这两个区别,首先要了解两个概念,①锁池EntryList ②等待池WaitSet。
1)notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会,而在锁池中的线程则不能获取到锁,只能等待其他机会获取锁
2)notify只会随机选取一个处于等待池中的线程及你如锁池去竞争获取锁的机会
八、yield
当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示,其并不会使当前线程让出占用的锁。
九、如何中断线程
已经被抛弃的方法
1)通过调用stop()方法停止线程
2)通过调用suspend()和resume()方法
这有可能会造成数据不同步的问题。目前所用的方法为,调用interrupt(),通知线程应该中断了
1)如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。
2)如果线程处于正常活动状态,那么会将该线程的中断标志设置为true。被设置中断标志的线程将继续正常运行,不受影响。