1,对于线程而言,start意味着多线程同步进行;run则表示在一条主线程上运行。
2,对于线程而言,可用于单线程和多线程。
提要 2,sleep和wait的使用及区别1,sleep是单独使用,wait需要配合notify使用。
2,对于sleep,Thread.sleep(括号内一般加时间:1000->1秒)。
3,对于wait,常用于加锁(加锁是主要用于守护线程)中,对某一线程设置等待,当需要该线程启动时会用notify开启线程。 *** 作为:this.wait();和this.notify();
4,注:此处只讲述建议过程,为记录学习准备。
一,Thread->继承Thread类对于Thread而言,可从一下几个例子看出:
1,使用多线程方式,利用Thread接口实现多线程的图片下载。 (1)下载器下载图片在idea中,先写个下载器
- 下载器:设置一个类区接收fileutils工具类的将路径中的URL变成文件的方法(copyURLTofile),然后在该方法中new一个URL和new一个name。
class webdownloaer{
//下载方法
protected void downloader(String url,String name){
try{
FileUtils.copyURLToFile(new URL(url),new File(name));
}catch (IOException e){
e.printStackTrace();
System.out.println("IO异常");
}
}
}
之后在类中继承Thread,并重写run方法。
- 线程类:将一个类继承线程thread,则该类转为线程类
public class demo2 extends Thread{
private String url;
private String name;
public demo2 (String url,String name){
this.url=url;
this.name=name;
}
@Override
public void run() {
webdownloaer webdownloaer=new webdownloaer();
webdownloaer.downloader(url,name);
System.out.println("下载文件名为:"+name);
}
3,在该类中加入主函数调用。
- 线程执行体:内部写的是下载器,new一个下载器类名,并执行执行该类的方法(将下载器运行起来)
public static void main(String[] args) {
demo2 t1=new demo2("http://www.kaotop.com/file/tupian/20220423/download.jpg","jpg");
demo2 t2=new demo2("http://www.kaotop.com/file/tupian/20220423/download.jpg","jpg");
demo2 t3=new demo2("http://www.kaotop.com/file/tupian/20220423/download.jpg","jpg");
t1.start();
t2.start();
t3.start();
}
此处的主函数中加入的是一个图片链接,如果下载成功,则可证明Thread方法使用成功。
4,执行截图。
原理:利用两个进程分别抢占资源,定义一个进程为兔子,另外一个进程为乌龟。当某一个进程先执行到一个判定条件(如:跑完一百步时)为胜利者。
1,在这里插入代码片让类继承Thread,并重写run方法。可以根据情况自行设置让兔子休息还是乌龟休息。
public class race implements Runnable{
private static String winner;
@Override
public void run() {
for (int i = 0; i <=100; i++) {
//模拟兔子休息
// if (Thread.currentThread().getName().equals("兔子")&&i%10==0){
// try {
// Thread.sleep(1);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//判断比赛是否结束
boolean flag=gameover(i);
if (flag){//比赛结束后停止程序
break;
}
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
}
}
2,加判定条件,如果胜利者产生(此处设置为先走完一百步),则进程停止。
private boolean gameover(int steps) {
if (winner!=null){//胜利者产生
return true;
}
{
if (steps>=100){
winner=Thread.currentThread().getName();
System.out.println("winner is"+winner);
return true;
}
}
return false;
}
3,在主函数中设置线程执行体,让两个进程启动。
public static void main(String[] args) {
race race=new race();
new Thread(race,"乌龟").start();
new Thread(race,"兔子").start();
}
4,注:执行截图。
做为对比,Runnable也会以同样的 *** 作下载。(此处只写出下载图片的代码)
下载图片->Runnable方式- 另:因为Runnable接口中没有start方法,所以,我们需要借用Thread。具体方法为:将Runnable接口的子类对象作为参数传递给Thread类的构造参数。
以下为具体 *** 作及代码:
1,依旧是建立一个下载器,方法和上诉相同。
class downloader{
//下载方法
protected void downloader(String url,String name){
try{
FileUtils.copyURLToFile(new URL(url),new File(name));
}catch (IOException e){
e.printStackTrace();
System.out.println("IO异常");
}
}
}
2,将类继承为Runnable,并重写run方法。
public class webdownloarderrun implements Runnable {
private String url;
private String name;
public webdownloarderrun (String url,String name){
this.url=url;
this.name=name;
}
@Override
public void run() {
webdownloaer webdownloaer=new webdownloaer();
webdownloaer.downloader(url,name);
System.out.println("下载文件名为:"+name);
}
3,线程执行体。不过要注意的是:由于Runnable没有start方法,如果使用run方法,就不会多线程了,此处的解决方法是:将Runnable接口的子类对象作为参数传递给Thread类的构造参数,这样借助Thread的start实现Runnable的多线程 *** 作。
不过说白了,这个Runnable就是借鸡下蛋。
public static void main(String[] args) {
webdownloarderrun t1=new webdownloarderrun("http://www.kaotop.com/file/tupian/20220423/download.jpg","1.jpg");
webdownloarderrun t2=new webdownloarderrun("http://www.kaotop.com/file/tupian/20220423/download.jpg","2.jpg");
webdownloarderrun t3=new webdownloarderrun("http://www.kaotop.com/file/tupian/20220423/download.jpg","3.jpg");
Thread tt1=new Thread(t1);
Thread tt2=new Thread(t2);
Thread tt3=new Thread(t3);
tt1.start();
tt2.start();
tt3.start();
}
4,效果图如下:
-
callable接口和其他两个相比,主要是多了个开启服务和关闭服务。
-
相比于Thread和Runnable,callable需要重写call方法。
以下为具体 *** 作(还是以下载为例)
下载的那谁(callable),过来排队1,依旧是童叟无欺的下载器(这个下载器真是买不了吃亏买不了上当,用着嘎嘎香)。
class webdownloaer{
//下载方法
protected void downloader(String url,String name){
try{
FileUtils.copyURLToFile(new URL(url),new File(name));
}catch (IOException e){
e.printStackTrace();
System.out.println("IO异常");
}
}
}
2,让你的类继承callable接口。并重写call方法。
public class test1 implements Callable {
private String url;
private String name;
public test1 (String url,String name){
this.url=url;
this.name=name;
}
@Override
public Boolean call() {
webdownloaer webdownloaer=new webdownloaer();
webdownloaer.downloader(url,name);
System.out.println("下载文件名为:"+name);
return true;
}
3,写个主函数,把那谁调动起来,不能废了半天劲写的东西放那吃灰吧,你说对不对?不过在这里需要注意啊,开启服务四件套:
(1)开启服务,不管干啥,先开就对了。具体是这样式儿的:ExecutorService service = Executors.newFixedThreadPool(3); 这个括号里面的是几你就有几个进程(你有几个进程,这括号里就是几)。
(2)将写的东西放到这里面执行一下(机器很傻,不给个指导啥都不会,真是 *** 碎了我这骄傲而又无处安放的心)。具体为:Future r1=service.submit(t1);括号里面的是你的执行体,别整歪了。
(3)将执行完的东西显示出了,要不机器说干了,你说没干,你俩不打起来?具体是这样滴:boolean rs1=r1.get();这里面你可以带参也可以不带,看你写的东西而定,我这简单,就没有参怎么带?我也很苦恼。
(4)把服务关了,中国人都讲究随手关门,你看,这就很nice。具体就这:service.shutdownNow();
public static void main(String[] args) throws ExecutionException, InterruptedException {
test1 t1=new test1("http://www.kaotop.com/file/tupian/20220423/download.jpg","1,jpg");
test1 t2=new test1("http://www.kaotop.com/file/tupian/20220423/download.jpg","2,jpg");
test1 t3=new test1("http://www.kaotop.com/file/tupian/20220423/download.jpg","3,jpg");
//创建执行服务,开启服务
ExecutorService service = Executors.newFixedThreadPool(3);
//提交执行
Future r1=service.submit(t1);
Future r2=service.submit(t2);
Future r3=service.submit(t3);
//获取结果
boolean rs1=r1.get();
boolean rs2=r2.get();
boolean rs3=r3.get();
//关闭服务
service.shutdownNow();
}
4,执行完成后,截图是这样式儿的:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)