多线程的一些细节:
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. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...

  2. IEnumerable接口的实现

    对象要实现可以迭代需IEnumerable接口并实现GetEnumerator方法.一下简单例子 public class SPEnumerable<T> : IEnumerable { ...

  3. robotframework笔记15

    资源和变量文件 用户关键字和变量 测试用例文件 和 测试套件 初始化文件只能用于文件在哪里 了,但 资源文件 提供一种机制来分享它们. 自 资源文件结构非常接近测试用例文件,它是 容易创建它们. 变量 ...

  4. 为SpringMvc项目安装BootStrap和AngularJs前端框架

    在我们"用SpringMVC写一个注册的小Demo"之前,我们学习一下如何给该项目安装Bootstrap和AngularJs的前端框架,这样我们就能轻松排版出漂亮的登录界面.我们采 ...

  5. JavaWeb基础: 第一个Web应用(Servlet)

    Servlet的生命周期 <servlet-mapping>和<servlet> Web应用的用户是通过指定浏览器中URL地址来访问Web应用提供的静态或者是动态资源,如果Se ...

  6. 学编程,学单词.....在学习中积累自己的单词(不断更新__ing)

    可以去肆意大话天下,可以去小民一般的言语,但是一定要清楚,知识的积累,至于心中,即便你说这粗俗的话,你的个性,气质依旧在那,比如北大的那啥教师(心中的典范),也只有这样,你才能低至市井,上至高阁... ...

  7. 《精通javascript》几个简单的函数

    转载http://www.cnblogs.com/jikey/archive/2011/07/25/2116696.html /** * 隐藏元素 * @param {String} elem */f ...

  8. Android实现Activity页面跳转切换动画特效

    了解Android程序设计的人应该知道,在Android 2.0之后有了overridePendingTransition(),其中里面两个参数,一个是前一个activity的退出,另一个activi ...

  9. ORACLE数据泵还原(IMPDP命令)【转】

      Oracle数据库还原IMPDP命令是相对于EXPDP命令的,方向是反向的.即对于数据库备份进行还原操作.一.知晓IMPDP命令 ? C:\>impdp -help Import: Rele ...

  10. linux tar 增量备份命令

    tar --newer-mtime "2013-09-17 00:00:00"   -zcvf /var/www/good.tar.gz    spider/