多线程的一些细节:
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使用》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 与MySQL的零距离接触 - 慕课网

    课程链接:与MySQL的零距离接触 环境配置: windows下安装mysql Download MySQL Installer for windows 课程目录 第1章 初涉MySQL     1- ...

  2. js高级程序设计(三)基本概念

    数据类型 ECMAscript中有五种简单数据类型Undefined,Null,Boolean,Number,String 还有一种复杂数据类型Object. typeof操作符 typeof可能返回 ...

  3. 【Linux】rpm -qa 和 rpm -q

    查询一个包是否被安装 # rpm -q < rpm package name>列出所有被安装的rpm package # rpm -qae.g. rpm -qa|grep "pc ...

  4. memset,memcpy,memcmp用法

    void* memset(void *s, int ch, size_t n); 将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII值. 例如:memset(lpMyStruct ...

  5. 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 ...

  6. 转载 网页打印时设置A4大小

    最近开发项目时遇到了网页打印的问题,这是问题之二,打印宽度设置 在公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot Per Inch)指标. 经过我仔细的测试,发现了网页打印中,默认采用 ...

  7. JS模块式开发

    问题:js文件须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难! C语言中模块开发-include ...

  8. c# 关键字delegate、event(委托与事件)[MSDN原文摘录][2]

    //Demo1:Declaring an event in an interface and implementing it in //a class. // event_keyword.cs usi ...

  9. 600万用户数据导入MYSQL、MSSQL、Oracle数据库方法【转】

      1.导入MySql数据库 参考文献:http://zhuaxia.org/blog/post/145 1.1.LOAD DATA INFILE语法 因为获得的数据库文件是一个文本文件www.csd ...

  10. 修改Widows网络设置提升网速

    可能很多用户不知道,我们在使用Windows系统连接Internet,系统默认保留20%的带宽,也就是说我们进行网络数据传输所能使用的带框仅为实际带宽的80%,但是我们修改网络设置或的最大带宽. 1. ...