《day16_多线程细节_Eclipse使用》
多线程的一些细节:
1,面试题:sleep方法和wait方法异同点是什么?
相同点:可以让线程处于冻结状态。
不同点:
1,
sleep必须指定时间。
wait可以指定时间,也可以不指定时间。
2,
sleep是时间到,线程处于临时阻塞或者运行。
wait如果没有指定时间,必须要通过notify或者notifyAll唤醒。
3,
sleep不一定非要定义在同步中,而wait必须要定义在同步中。
4,
都定义在同步中,
线程执行到sleep不会释放锁,
线程执行到wait会释放锁。
synchronized(obj)
{
//sleep(5000);
wait();//0 1 2
code...
} synchronized(obj)
{
notifyAll();//
code...
}
2,线程如何停止呢?
stop方法过时了,看描述发现,有其他解决方案。
线程结束,就是让线程任务代码执行完,run方法结束。
run方法咋结束呢?
run方法中通常都定义循环。只要控制住循环就可以了。 注意:万一线程在任务中处于冻结状态,那么它还能去判断标记吗?不能!
咋办?通过查阅stop方法的描述,发现提供了一个解决方案。
文档中的解决方案:
如果目标线程等待很长时间(例如基于一个条件变量),
则应使用 interrupt 方法来中断该等待。
所谓的中断并不是停止线程。
interrupt的功能是:将线程的冻结状态清除,让线程恢复到运行状态(让线程重新具备cpu的执行资格。)
因为是强制性的所以会有异常发生,可以在catch中捕获异常。在异常处理中,改变标记,让循环结束。让run方法结束。
3,守护线程,后台线程,一般创建的都是前台线程。
前台后台线程运行时都是一样的,获取cpu的执行权执行。
只有结束的时候有些不同。
前台线程要通过run方法结束,线程结束。
后台线程也可以通过run方法结束,线程结束,还有另一种情况。
当进程中所有的前台线程都结束了,这时无论后台线程处于什么样的状态,都会结束,从而线程结束。
进程结束依赖的都是前台线程。 4.线程的优先级:用数字标识的。 1-18
其中默认的初始优先级是5. 最明显的三个优先级 1 ,5 ,10.
setPriority(Thread.MAX_PRIORITY);
5,线程组:ThreadGroup.可以通过Thread的构造函数明确新线程对象所属的线程组。
线程组的好处,可以对多个同组线程进行统一的操作。
默认都属于main线程组。 6,开发中线程的匿名内部类体现。
//day16多线程细节&Eclipse的使用。(需求一:解决妖的问题。) /*
需求:
资源有姓名和性别。
两个线程:
一个负责给姓名和性别赋值。
一个负责获取姓名和性别的值。 参阅ThreadTest2.java文件。 要求:1,运行一下,解决程序中“妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题。 要求2:实现正确数据的间隔输出 如:
张飞--男
rose--女女女
张飞--男
rose--女女女 要求3:对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。 要求4:将程序改成JDK1.5的Lock Conditon接口。 */ //描述资源
class Resource
{
String name;
String sex;
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(x==0)
{
r.name = "张飞";
r.sex = "男";
}
else
{
r.name = "rose";
r.sex = "女女女";
}
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务。
class Output implements Runnable
{
private Resource r;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
System.out.println(r.name+"...."+r.sex);
}
}
}
}
class ThreadTest2
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
//day16多线程细节%Eclipse的使用。(需求二:正确数据的间隔输出)
/*
需求:
资源有姓名和性别。
两个线程:
一个负责给姓名和性别赋值。
一个负责获取姓名和性别的值。 参阅ThreadTest2.java文件。 要求:1,运行一下,解决程序中“妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题。 要求2:实现正确数据的间隔输出 如:
张飞--男
rose--女女女
张飞--男
rose--女女女
使用等待唤醒机制。
wait(),notify(),notifyAll(); 对于等待都需要判断,定义条件 要求3:对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。 要求4:将程序改成JDK1.5的Lock Conditon接口。 */
//描述资源
class Resource
{
String name;
String sex;
//定义标记
boolean flag=false;
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
try{r.wait();}catch(InterruptedException e){}
if(x==0)
{
r.name = "张飞";
r.sex = "男";
}
else
{
r.name = "rose";
r.sex = "女女女";
}
r.flag = true;
r.notify();
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务。
class Output implements Runnable
{
private Resource r;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)
try{r.wait();}catch(InterruptedException e){}
System.out.println(r.name+"...."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
class ThreadTest2_2
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
//day16多线程细节%Eclipse的使用。(需求二:正确数据的间隔输出)
/*
需求:
资源有姓名和性别。
两个线程:
一个负责给姓名和性别赋值。
一个负责获取姓名和性别的值。 参阅ThreadTest2.java文件。 要求:1,运行一下,解决程序中“妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题。 要求2:实现正确数据的间隔输出 如:
张飞--男
rose--女女女
张飞--男
rose--女女女
使用等待唤醒机制。
wait(),notify(),notifyAll(); 对于等待都需要判断,定义条件 要求3:对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。 要求4:将程序改成JDK1.5的Lock Conditon接口。
Lock替换了同步函数或者同步代码块。 Condition替代了 监视器方法,将监视器方法从锁上分离出来,单独封装Condition对象。 */
//描述资源
class Resource
{
private String name;
private String sex;
//定义标记
private boolean flag=false; //赋值功能。
public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
//获取值。
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"........"+sex);
flag = false;
this.notify();
}
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("张飞","男");
}
else
{
r.set("rose","女女女");
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务。
class Output implements Runnable
{
private Resource r;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ThreadTest2_3
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
//day16多线程细节%Eclipse的使用。(需求二:正确数据的间隔输出)
/*
需求:
资源有姓名和性别。
两个线程:
一个负责给姓名和性别赋值。
一个负责获取姓名和性别的值。 参阅ThreadTest2.java文件。 要求:1,运行一下,解决程序中“妖”的问题。
分析过程:
加入同步,必须保证同一个锁,解决妖的问题。 要求2:实现正确数据的间隔输出 如:
张飞--男
rose--女女女
张飞--男
rose--女女女
使用等待唤醒机制。
wait(),notify(),notifyAll(); 对于等待都需要判断,定义条件 要求3:对代码进行重构。
将name,sex私有化,资源类提供对其访问的方法。 要求4:将程序改成JDK1.5的Lock Conditon接口。
Lock替换了同步函数或者同步代码块。 Condition替代了 监视器方法,将监视器方法从锁上分离出来,单独封装Condition对象。 */
//描述资源 import java.util.concurrent.locks.*;
class Resource
{
private String name;
private String sex;
//定义标记
private boolean flag=false; //1.先创建锁对象。
private final Lock lock = new ReentrantLock(); //通过锁对象获取监视器对象。
private Condition con = lock.newCondition(); //赋值功能。
public void set(String name,String sex)
{
lock.lock();
try{
if(flag)
try{con.await();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
con.signal();
}finally{
lock.unlock();
}
}
//获取值。
public void out()
{
lock.lock();
try{
if(!flag)
try{con.await();}catch(InterruptedException e){}
System.out.println(name+"........"+sex);
flag = false;
con.signal();
}finally{
lock.unlock();
}
}
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("张飞","男");
}
else
{
r.set("rose","女女女");
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务。
class Output implements Runnable
{
private Resource r;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ThreadTest2_4
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
class ThreadTest
{
public static void main(String[] args)
{
/*
new Thread(){
public void run()
{
for(int x=0;x<40;x++)
{
System.out.println(Thread.currentThread().getName()+"..X.."+x);
}
}
}.start(); Runnable r = new Runnable(){
public void run(){
for(int x=0;x<40;x++)
{
System.out.println(Thread.currentThread().getName()+"..Y.."+x);
}
}
}; new Thread(r).start(); for(int x=0;x<40;x++)
{
System.out.println(Thread.currentThread().getName()+"..Z.."+x);
} */
//面试题:
new Thread(new Runnable()
{
public void run()
{
System.out.println("runnbable run");
}
}){
public void run()
{
System.out.println("subthread run");
}
}.start();
}
} /*
class Thread
{
private Runnable r;
Thread(Runnable r)
{
this.r = r;
}
public void run()
{
if(r!=null)
{
r.run();
}
}
public void start()
{
run();
}
} class SubThread extends Thread
{
public void run()
{
System.out.println("subthread run");
}
} Runnable r = new Runnable()
{
public void run()
{
System.out.println("runnable run");
}
} SubThread t = new SubThread(r);
t.start();
*/
//演示停止线程。
class Demo implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try
{
wait();//t1 t2
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().toString()+"..."+e.toString());
changeFlag();
}
System.out.println(Thread.currentThread().getName()+"--->");
}
}
//对标记的修改方法。
public void changeFlag()
{
flag = false;
}
} class StopThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo(); Thread t1 = new Thread(d,"旺财");
Thread t2 = new Thread(d,"小强");
t1.start();
//将t2标记为守护线程,也叫后台线程。
t2.setDaemon(true);
t2.start(); int x = 0;
while(true)
{
if(++x == 50)//条件满足。
{
// d.changeFlag();//改变线程任务代码标记。让其他线程也结束。
//强制对t1线程对象中断状态的清除。强制让其恢复到运行状态。
t1.interrupt();
//强制对t1线程对象中断状态的清除。强制让其恢复到运行状态。
t2.interrupt();
break;//跳出循环。主线程可以结束。
}
System.out.println("main------->"+x);
}
System.out.println("over");
}
}
class Demo implements Runnable
{
public void run()
{
for(int x=1;x<=20;x++)
{
System.out.println(Thread.currentThread().getName()+"---->"+x);
Thread.yield();//线程临时暂停。将执行权释放。让其他线程有机会获取。
}
} }
class JoinThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d); //主线程执行到这里,知道t1要加入执行,主线程释放了执行权,和执行资格,并处于冻结状态
//什么时候恢复呢?等待t1线程执行完。
t1.start();
t2.start();
//try{t1.join();}catch(InterruptedException e){}//用于临时加入一个线程,该线程运算完,程序才会继续执行。 for(int x=1;x<=20;x++)
{
System.out.println("main------->"+x);
}
System.out.println("over");
}
}
《day16_多线程细节_Eclipse使用》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- 与MySQL的零距离接触 - 慕课网
课程链接:与MySQL的零距离接触 环境配置: windows下安装mysql Download MySQL Installer for windows 课程目录 第1章 初涉MySQL 1- ...
- js高级程序设计(三)基本概念
数据类型 ECMAscript中有五种简单数据类型Undefined,Null,Boolean,Number,String 还有一种复杂数据类型Object. typeof操作符 typeof可能返回 ...
- 【Linux】rpm -qa 和 rpm -q
查询一个包是否被安装 # rpm -q < rpm package name>列出所有被安装的rpm package # rpm -qae.g. rpm -qa|grep "pc ...
- memset,memcpy,memcmp用法
void* memset(void *s, int ch, size_t n); 将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII值. 例如:memset(lpMyStruct ...
- Echart多图联动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 转载 网页打印时设置A4大小
最近开发项目时遇到了网页打印的问题,这是问题之二,打印宽度设置 在公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot Per Inch)指标. 经过我仔细的测试,发现了网页打印中,默认采用 ...
- JS模块式开发
问题:js文件须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难! C语言中模块开发-include ...
- c# 关键字delegate、event(委托与事件)[MSDN原文摘录][2]
//Demo1:Declaring an event in an interface and implementing it in //a class. // event_keyword.cs usi ...
- 600万用户数据导入MYSQL、MSSQL、Oracle数据库方法【转】
1.导入MySql数据库 参考文献:http://zhuaxia.org/blog/post/145 1.1.LOAD DATA INFILE语法 因为获得的数据库文件是一个文本文件www.csd ...
- 修改Widows网络设置提升网速
可能很多用户不知道,我们在使用Windows系统连接Internet,系统默认保留20%的带宽,也就是说我们进行网络数据传输所能使用的带框仅为实际带宽的80%,但是我们修改网络设置或的最大带宽. 1. ...