多线程的一些细节:
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. Google V8扩展利器发布:v8-native-binding-generator

    用C++扩展Google V8很简单,但是类比较多时还是很烦的.前段时间开发cantk-runtime-v8时,我写了一个代码产生器v8-native-binding-generator,让扩展Goo ...

  2. Eclipse 添加SVN

    第一种方法没试 第二种方法  可以使用 现在版本 最新为 1.10.x 1.下载最新的Eclipse,我的版本是3.7.2 indigo(Eclipse IDE for Java EE Develop ...

  3. java操作数据库出现(][SQLServer 2000 Driver for JDBC]Error establishing socket.)的问题所在即解决办法

    在进行jdbc直接操作数据库时    : 我们需要对该工程进行一次导包(引入"msbase.jar" "mssqlserver.jar" "msuti ...

  4. 学习HTML5之塔克大战(详细记录)

    学了一些HTML5的一些基本知识,开始学习制作...... 介绍一些基本知识:  px(像素)--->1px等于多少? 1cm or 2cm -->no  no no! (1).像素是一个 ...

  5. file类之目录

    可以解决的问题是:                有时需要列出目录下指定类型的文件,比如java,txt等扩展名的文件,可以使用File类的下述两个方法,列出指定类型的文件. /* file类实现两个 ...

  6. collectionView初始化

    collectionView初始化时一定要加layout.不然会报错: UICollectionView must be initialized with a non-nil layout param ...

  7. Java 迭代器理解

    1.Iterator(迭代器) 作为一种设计模式,迭代器可以用于遍历一个对象,对于这个对象的底层结构不必去了解. java中的Iterator一般称为“轻量级”对象,创建它的代价是比较小的.这里笔者不 ...

  8. ZZC语言代码风格

    程序员之路--关于代码风格 优秀的代码风格如同一身得体的打扮,能够给人以良好的印象.初学程序设计,首先必须建立良好的编程习惯,这其中就包括代码风格.本文就代码风格中的几个重点问题进行了讨论,并在文后给 ...

  9. BZOJ1932 [Shoi2007]Setstack 集合堆栈机

    妈呀...clj大爷太强啦! 原来还有set_union和set_intersection这种东西... 于是只要把栈顶的每个元素hash一下记录到一个vector里去就好了 /*********** ...

  10. BZOJ3928 [Cerc2014] Outer space invaders

    第一眼,我勒个去...然后看到n ≤ 300的时候就2333了 首先把时间离散化,则对于一个时间的区间,可以知道中间最大的那个一定要被选出来,然后把区间分成左右两份 于是区间DP就好了,注意用左开右开 ...