线程与进程的具体解释,区别等不说了,不会那不用参加秋招了。
一、多线程的实现方法
1、主线程中的等待发
缺点:线程多的化就会让代码显得冗余。
2、添加join进行等待
不够细粒度。
public class CycleWait implements Runnable{
private String value;
@Override
public void run() {
try {
Thread.currentThread().sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
value="we are ready";
}
public static void main(String[] args) throws InterruptedException {
CycleWait cycleWait=new CycleWait();
Thread thread=new Thread(cycleWait);
thread.start();//一定要让线程开始执行
// while (cycleWait.value==null){
// try {
// Thread.currentThread().sleep(100);
// }catch (InterruptedException e){
// e.printStackTrace();
// }
// }//方法1
// thread.join();//方法2
System.out.println(cycleWait.value);
}
3、通过FuntureTsak和线程池
创建一个MyCallablelei用于重写Call函数
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
String value="test";
System.out.println("Ready to work");
Thread.currentThread().sleep(5000);
System.out.println("tesk done");
return value;
}
}
①、FuntureTask方法
public class FutureTaskDame {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String > task=new FutureTask<String>(new MyCallable());
new Thread(task).start();
if (!task.isDone()){
System.out.println("task has not finished,please wait!");
}
System.out.println("task return"+task.get());
}
}
特别关注一下isDone()函数跟get函数,isDone()用于处理call函数是否执行完了没有,get分为两个,一个是无参,用于阻塞调用它的线程一直到call函数执行完了没有。有参的里面有时间参数用于处理时间超时的情况。
②、创建线程池
public class ThreadPoolDame {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService newCachedThreadPool= Executors.newCachedThreadPool();
Future<String> future=newCachedThreadPool.submit(new MyCallable());
if (!future.isDone()){
System.out.println("task has not finished,please wait!");
}
System.out.println(future.get());
newCachedThreadPool.shutdown();//线城池一定要关闭
}
}
仔细深究源代码就会发现FuturTask继承RunnableFuture接口而RunnableFuture接口有继承Future接口和Runnable。
二、run函数传参的方法
1、构造函数传参
2、成员变量或方法传参
定义变量或者时set方法赋值
3、回调函数传参
写代码块等
三、Thread中start和run的方法
1、start创建了一个线程并启动,同时调用了run函数
2、run只是Thread类中的一个方法
四、Thread和Runnable的区别
1、Thread是类,Runnable是接口
2、Thread类继承了Runnable接口
五、线程的六种状态
1、新建
2、运行
3、堵塞
4、结束
5、有时间的等待
①、sleep()方法
②、wait(),join()加时间
③、LockSupport.park
Nanos()方法和LockSupport.park
Until()
6、没有时间的等待
①、wait(),join()加时间
②、LockSupport.park()
六、sleep和wait的区别
①、sleep可以运用在任何地方
②、wait只能运用在synchronized方法或者synchroized快中
③、sleep是Thread中的方法,wait是Object方法
原因:
sleep结束只释放CPU,不会导致锁行为改变
wait不仅让出CPU还会释放已占有的同步资源锁
举个栗子
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock =new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lock");
synchronized (lock){
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
lock.wait(1000);
System.out.println("thread A is done");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lock");
synchronized (lock){
try {
System.out.println("thread B get lock");
System.out.println("thread is sleeping 10ms");
Thread.sleep(10);
System.out.println("thread B is done");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
}
}
运行结果
thread A is waiting to get lock
thread A get lock
thread B is waiting to get lock
thread A do wait method
thread B get lock
thread is sleeping 10ms
thread B is done
thread A is done
从例子中可以看出,线程A先执行,当线程A要睡20秒时,线程B就会开始执行,但进入synchroized要获取锁,此时的锁在线程A这里所以B不能执行,当A运行完wait后就会放出锁,此时B也开始执行了。
我们先运行sleep在运行wait看看
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock =new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lock");
synchronized (lock){
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
Thread.sleep(1000);
System.out.println("thread A is done");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lock");
synchronized (lock){
try {
System.out.println("thread B get lock");
System.out.println("thread is sleeping 10ms");
lock.wait(10);
System.out.println("thread B is done");
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
}
}
结果
thread A is waiting to get lock
thread A get lock
thread B is waiting to get lock
thread A do wait method
thread A is done
thread B get lock
thread is sleeping 10ms
thread B is done
可以看出thread A do wait method和
thread A is done是连这显示的,所以sleep不会让出锁,只有线程执行结束了才可以。
七、yield函数的作用
给线程调度机一个暗示,不会让出当前线程已占用的锁。
八、中断函数interrupt的运用(多理解看代码)
①、堵塞函数会抛出异常,但要看具体情况
interr详细讲解
②、正在运行的函数则只是将中断标志位至ture,继续运行不受影响。
阻塞状态代码
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Runnable interruptTask=new Runnable() {
@Override
public void run() {
int i=0;
try {
while (!Thread.interrupted()){
Thread.sleep(100);
i++;
System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getState()+")"+i);
}
}catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getState()+") catch InterruptedException");
}
}
};
Thread t1=new Thread(interruptTask,"t1");
System.out.println(t1.getName()+"("+t1.getState()+") is new");
t1.start();
System.out.println(t1.getName()+"("+t1.getState()+") is started");
Thread.sleep(300);
t1.interrupt();
System.out.println(t1.getName()+"("+t1.getState()+") is interrupted");
Thread.sleep(300);
System.out.println(t1.getName()+"("+t1.getState()+") is interrupted now");
}}
运行状态
public class InterruotDemo2 extends Thread{
public void run(){
while(true){
if(Thread.currentThread().isInterrupted()){
System.out.println("Someone interrupted me.");
}
else{
System.out.println("Thread is Going...");
}
}
}
public static void main(String[] args) throws InterruptedException {
InterruotDemo2 t1=new InterruotDemo2();
t1.start();
Thread.sleep(3000);
t1.interrupt();
}
}