多线程学习1(线程的三种创建方式,lambda表达式,线程的状态)
一.线程的三种创建方式
1.继承Thread类
package demo01;//创建线程方式一,继承thread类 ,重写run()方法,调用start开启线程
//总结:线程开始,不一定立即执行,由cpu调度执行
public class TestThread extends Thread{
@Override
public void run(){
//run方法线程体
for(int i=0;i<20;i++){
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args){
//main线程
//创建一个线程对象,调用start方法,开启线程
TestThread testThread1 = new TestThread();
testThread1.start();
for (int i = 0; i < 500; i++) {
System.out.println("我在学习多线程"+i);
}
}
} 2.实现Runable接口
优点:避免单继承的局限性,灵活方便,方便同一个对象被多个线程所使用
package demo01;
//创建线程方式2,实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{
@Override
public void run(){
//run方法线程体
for(int i=0;i<20;i++){
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args){
//创建runnable接口的实现类对象
TestThread3 testThread3 = new TestThread3();
//创建线程对象,通过线程对象来开启线程,代理
//Thread hread = new Thread(testThread3);
//thread.start();
new Thread(testThread3).start();
for (int i = 0; i < 500; i++) {
System.out.println("我在学习多线程"+i);
}
}
}3.实现callable接口
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
public TestCallable(String url,String name){
this.url=url;
this.name=name;
}
//下载图片线程执行体
@Override
public Boolean call(){
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为"+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable t1 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","1.jpg");
TestCallable t2 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","2.jpg");
TestCallable t3 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","3.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> r1= ser.submit(t1);
Future<Boolean> r2= ser.submit(t2);
Future<Boolean> r3= ser.submit(t3);
//获取结果
boolean rs1= r1.get();
boolean rs2= r2.get();
boolean rs3= r3.get();
//关闭服务
ser.shutdownNow();
}
}
class WebDownloader{
//下载方法
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常");
}
}
二.lambda表达式
package lambda;
/*
推导lambda表达式
*/
public class TestLamda1{
//3.静态内部类
static class Like2 implements Ilike{
@Override
public void lambda() {
System.out.println("i like lambda2");
}
}
public static void main(String[] args) {
Ilike like = new Like();
like.lambda();
Ilike like2 = new Like2();
like2.lambda();
//4.局部内部类
class Like3 implements Ilike{
@Override
public void lambda() {
System.out.println("i like lambda3");
}
}
Ilike like3 = new Like3();
like3.lambda();
//5.匿名内部类
like = new Ilike() {
@Override
public void lambda() {
System.out.println("i like lambda4");
}
};
like.lambda();
//6.用lambda简化
like = ()->{
System.out.println("i like lambda5");
};
like.lambda();
}
}
//1.定义一个函数接口(只有一个抽象方法的接口)
interface Ilike{
void lambda();
}
//2.实现类
class Like implements Ilike{
@Override
public void lambda() {
System.out.println("i like lambda");
}
}
三.线程状态
1.线程的停止
不推荐使用jdk提供的stop(),destroy()方法,推荐让线程自己停下来,建议使用一个标志位,当flag=false线程终止
package state;
//测试停止线程
//1.建议线程正常停止--->利用次数,不建议死循环
//2.建议使用标志位--->设置一个标志位
//3.不要使用stop或destroy等过时或者JDK不建议使用的方法
public class TestStop implements Runnable{
//标志位
boolean flag = true;
@Override
public void run(){
int i=0;
while(flag){
System.out.println("run...Thread"+i++);
}
}
//设置一个公开的方法停止线程,装换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop testStop =new TestStop();
new Thread(testStop).start();
for(int i = 0; i < 1000; i++){
System.out.println("main" + i);
if(i == 900){
//调用stop方法切换标志位,让线程停止
testStop.stop();
System.out.println("线程停止了");
}
}
}
}
2.线程的休眠
sleep不会释放锁
可以放大问题的发生性,模拟网络延时
可以模拟倒计时
package state;
import demo01.TestThread4;
//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable {
//票数
int ticketNums = 10;
@Override
public void run(){
while(true){
if(ticketNums <= 0){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"获得了" + ticketNums-- + "票");
}
}
public static void main(String[] args) {
TestThread4 testThread4 = new TestThread4();
new Thread(testThread4, "小明").start();
new Thread(testThread4, "老师").start();
new Thread(testThread4, "黄牛").start();
}
}
3.线程礼让Yield
将线程从运行太转为就绪态
package state;
//测试礼让线程
//礼让不一定成功,看cpu心情
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield, "a").start();
new Thread(myYield, "b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始执行");
Thread.yield(); //礼让
System.out.println(Thread.currentThread().getName()+"线程停止执行");
}
}4.线程强制执行
可以想象为插队,强制一个线程执行直至其结束
package state;
//测试Join方法,想象为插队
public class TestJoin implements Runnable{
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000; i++) {
System.out.println("线程vip来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动线程
TestJoin testJoin = new TestJoin();
Thread thread=new Thread(testJoin);
thread.start();
for (int i = 0; i < 500; i++) {
if(i==200){
thread.join();
}
System.out.println("main"+i);
}
}
}5.观测线程状态state
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
package state;
//观察线程状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("///");
});
//观察状态
Thread.State state = thread.getState();
System.out.println(state);
//观察启动
thread.start();
state = thread.getState();
System.out.println(state);
while(state != Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
Thread.sleep(100);
state = thread.getState();//更 新进程状态
System.out.println(state);
}
}
}6线程优先级
高优先级的线程更容易执行,但还是要看cpu的心情
package state;
//测试线程的优先级
public class TestPriority {
public static void main(String[] args) {
//主线程默认优先级
System.out.println(Thread.currentThread().getName() + "-->" +Thread.currentThread().getPriority());
MyPriority myPriority = new MyPriority();
Thread t1= new Thread(myPriority);
Thread t2= new Thread(myPriority);
Thread t3= new Thread(myPriority);
Thread t4= new Thread(myPriority);
Thread t5= new Thread(myPriority);
Thread t6= new Thread(myPriority);
//设置优先级,再启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(4);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);
t4.start();
t5.setPriority(8);
t5.start();
t6.setPriority(7);
t6.start();
}
}
class MyPriority implements Runnable{
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + "-->" +Thread.currentThread().getPriority());
}
} 7.守护线程
虚拟机必须确保用户线程执行完毕,不用等待守护线程执行完毕,守护线程常用来监控内存,垃圾回收,后台记录操作日志
package state;
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true); //设置守护线程
thread.start();
new Thread(you).start(); //用户线程启动
}
}
//上帝
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("上帝保佑着你");
}
}
}
//你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("开心的活着");
}
System.out.println("==============goodebye!world!============");
}
}
格力公司福利 242人发布