并发安全问题,异步效率低。
同步效率低,但是没有并发问题
五种状态!
Match
睡眠以后,就是交替执行!
这里调用r.start()方法!
不要调用r.run()方法,调用了此方法以后变成了同步操作main线程!
main线程自动开启!!不用方法开启
public class Match {
//主线程
public static void main(String[] args) {
Runner r=new Runner();
r.start();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
}
}
/**
*
* 线程继承Thread类
* @author 戴尔
*
*/
class Runner extends Thread{
/**
*
* 线程所要执行的
*/
public void run(){
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Match1
交替进行; 隐含了二个线程,主线程(main线程) 垃圾回收线程!GC会看着对垃圾进行回收!
package com.laoluo.demo1;
import java.util.Random;
public class Match1 extends Thread{
Integer speed=new Random().nextInt(100);
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//睡眠 每执行一次循环,睡眠多少次毫秒
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(this.currentThread().getName()+"已经前进"+(i * speed)+"米("+speed+"米/秒)");
}
}
//交替执行的线程 五个 线程 主线程 GC垃圾回收线程
// 刘翔 小陈 老钱 三个线程
public static void main(String[] args) {
Match1 xx=new Match1();
xx.setName("刘翔");
Match1 xiaochen=new Match1();
xiaochen.setName("小陈");
Match1 laoqian=new Match1();
laoqian.setName("老钱");
//组织Start的 过程最好在一起
xx.start();
xiaochen.start();
laoqian.start();
}
}
Match2
只有thread 才有start方法 所以runnable依赖 加载thread
所以我创建了Thread来实现 runnable线程
Thread 才有getName,
对应的线程接口 有一个run方法 Thread就是对run方法的一个实现
package com.laoluo.demo2;
import java.util.Random;
//Thread 才有getName
//对应的线程接口 有一个run方法 Thread就是对run方法的一个实现
public class Match2 implements Runnable{
Integer speed=new Random().nextInt(100);
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//睡眠 每执行一次循环,睡眠多少次毫秒
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"已经前进"+(i * speed)+"米("+speed+"米/秒)");
}
}
public static void main(String[] args) {
//每次执行的线程 都不一样 秒速
//只有thread 才有start方法 所以runnable依赖 加载thread
//依赖 therad来去实现runnable接口
Match2 xx=new Match2();
Thread t=new Thread(xx,"刘翔");
Match2 xiaochen=new Match2();
Thread t1=new Thread(xiaochen,"小陈");
Match2 laoqian=new Match2();
Thread t2=new Thread(xiaochen,"老钱");
t.start();
t1.start();
t2.start();
}
}
Match3
Callable接口有返回值!!!声明的异常在方法上面!
Runnable没有返回值!!! 异常抛出在run方法内部
ExecutorService线程池!!!限定线程的数量通过!!线程池的调度器
线程池是保持开启的! 没有这个关闭 es.shutdown(); 他会一直等待 线程的到来!
package com.laoluo.demo3;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
//方法里面没有 name方法 只能自己做
public class Match3 implements Callable<Integer> {
//call方法 跟run方法相比 call 有返回值 可以抛出异常 在
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Integer call() throws Exception {
Integer speed=new Random().nextInt(100);
int distinct=0;
for (int i= 0; i < 100; i++) {
Thread.sleep(100L);
distinct =speed * i;
System.out.println(this.name+"已经前进"+(i * speed)+"米("+speed+"米/秒)");
}
return distinct;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建一个线程池
//线程池的调度器
//数据库连接池的含义 规定限制通过的线程!!
ExecutorService es=Executors.newFixedThreadPool(3);
Match3 xx=new Match3();
xx.setName("刘翔");
Match3 xiaochen=new Match3();
xiaochen.setName("小陈");
Match3 laoqian=new Match3();
laoqian.setName("老钱");
//提交任务的操作
Future<Integer> result=es.submit(xx);
Future<Integer> result2=es.submit(xiaochen);
Future<Integer> result1=es.submit(laoqian);
System.out.println(xx.getName()+"跑了"+result.get());
System.out.println(xiaochen.getName()+"跑了"+result1.get());
System.out.println(laoqian.getName()+"跑了"+result2.get());
//线程池也是常开的! 没有这个关闭 他会一直等待 线程的到来!
es.shutdown();
}
}
Match4
如果没有线程睡眠!!!!输出值是
a:0 b:0
造成结果的原因是 你的main线程比你的 match线程执行快 还没有执行完match4相关的操作 main线程就已经执行完了
xx.stop(); //过期的数据 锁失效!!!突然给你停止线程池(强制)
突然给你强制性关闭线程!!!!
输出结果就是: 半途给你关闭线程
a:1 b:0
package com.pb.demo4;
//造成结果的原因是 你的main线程比你的 match线程执行快 还没有执行完match4相关的操作 main线程就已经执行完了
public class Match5 extends Thread {
int a;
int b;
@Override
public void run() {
//锁的概念
//上厕所 一个一个进
synchronized (this) {
a++;
//延时2秒操作
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b++;
}
}
public void print() {
System.out.println("a:" + a);
System.out.println("b:" + b);
}
public static void main(String[] args) throws InterruptedException {
Match5 m = new Match5();
m.start();
Thread.sleep(2000L);
//停止线程操作
m.stop(); //过期的数据,但是面试会问到,强制停止线程是synchronized失效了
m.print(); //调用了打印的方法
}
}
Match5
注意main线程效率快!会造成别的线程还没开始 他就跑完了!
图一:死循环输出:不会停止!
Thread-0 true
Thread-0 true
Thread-0 true
Thread-0 true
package com.laoluo.demo5;
public class Match5 extends Thread{
@Override
public void run() {
while(Thread.currentThread().isInterrupted()){
System.out.println(Thread.currentThread().getName()+"\t"+Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
//main线程 执行效率太快 ,
Match5 m=new Match5();
m.start();
// Thread.sleep(1000L);
//标记,
//不为真的时候退出了
m.interrupt();
}
}
图二:
当while(!Thread.currentThread().isInterrupted()) 不为true为false的时候!就停止退出来
标识:m.interrupt(); 告诉线程我要开始推出了false
.isInterrupted()拿到标识 是有准备的退出
package com.laoluo.demo5;
public class Match5 extends Thread{
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
System.out.println(Thread.currentThread().getName()+"\t"+Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
//main线程 执行效率太快 ,
Match5 m=new Match5();
m.start();
Thread.sleep(1000L);
//标记,
//不为真的时候退出了
m.interrupt();
}
}
这也是一种退出线程的方式;
人为方式。 例如:break; continue;return;等等也能让线程安全退出
package com.pb.demo5;
public class Match6 extends Thread{
@Override
public void run() {
//是有准备的退出。不是硬退
// while(!Thread.currentThread().isInterrupted()) {
// System.out.println(Thread.currentThread().getName()+"\t" + Thread.currentThread().isInterrupted());
// }
int i = 0;
while(i < 1000) {
//认为的通过指令方式让线程退出
if(i == 50) {
break;
}
System.out.println(Thread.currentThread().getName() + " \t " + i);
i++;
}
}
public static void main(String[] args) throws InterruptedException {
//main线程效率太快了,main线程结束了
Match6 m = new Match6();
m.start();
//Thread.sleep(1000L);
//标记,告诉线程我要开始推出了===false
//不为真的时候退出了
//m.interrupt(); //给线程退出的一个指令
}
}