基础学习day12--多线程一线程之间的通信和常用方法
一、线程之间的通信
1.1、线程之间的通信方法
多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信。
等待/唤醒机制涉及的方法:
1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2. notify():唤醒线程池中的一个线程(任何一个都有可能)。
3. notifyAll():唤醒线程池中的所有线程。
备注
1、这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法。
2、必须要明确到底操作的是哪个锁上的线程!
3、wait和sleep区别?
1)wait可以指定时间也可以不指定。sleep必须指定时间。
2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
为什么操作线程的方法wait、notify、notifyAll定义在了object类中,因为这些方法是监视器的方法,监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方式一定在object类中。
1.2、两个线程交替打印1-100
package com.pb.thread.demo1; public class Demo { private int num=1; /*
* 打印偶数
*/
public synchronized void put(){ if(num%2==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} notify();
System.out.println(Thread.currentThread().getName()+","+num);
num++;
}
/*
* 打印奇数
*/
public synchronized void get(){
if(num%2!=0){
try {
//当前线程等待
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//唤醒另一等待中的线程
notify();
System.out.println(Thread.currentThread().getName()+","+num);
num++;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
} }
package com.pb.thread.demo1;
/**
* 打印偶数
* @author denny
*
*/
public class A implements Runnable { Demo demo;
public A(Demo demo){
this.demo=demo;
} @Override
public void run() {
while(demo.getNum()<100){
demo.put(); } } }
package com.pb.thread.demo1;
/**
* 打印奇数
* @author denny
*
*/
public class B implements Runnable {
Demo demo; public B(Demo demo) {
this.demo = demo;
} @Override
public void run() {
while(demo.getNum()<100){
demo.get(); } } }
测试类
package com.pb.thread.demo1;
/**
* 2个线程交替打印1-100
* @author denny
*
*/
public class Test { public static void main(String[] args) {
Demo demo=new Demo();
A a=new A(demo);
B b=new B(demo);
Thread t1=new Thread(a);
Thread t2=new Thread(b);
t1.start();
t2.start(); } }
结果:
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
Thread-0,1
Thread-1,2
Thread-0,3
Thread-1,4
Thread-0,5
Thread-1,6
Thread-0,7
Thread-1,8
Thread-0,9
Thread-1,10
Thread-0,11
Thread-1,12
Thread-0,13
Thread-1,14
Thread-0,15
Thread-1,16
Thread-0,17
Thread-1,18
Thread-0,19
Thread-1,20
Thread-0,21
Thread-1,22
Thread-0,23
Thread-1,24
Thread-0,25
Thread-1,26
Thread-0,27
Thread-1,28
Thread-0,29
Thread-1,30
Thread-0,31
Thread-1,32
Thread-0,33
Thread-1,34
Thread-0,35
Thread-1,36
Thread-0,37
Thread-1,38
Thread-0,39
Thread-1,40
Thread-0,41
Thread-1,42
Thread-0,43
Thread-1,44
Thread-0,45
Thread-1,46
Thread-0,47
Thread-1,48
Thread-0,49
Thread-1,50
Thread-0,51
Thread-1,52
Thread-0,53
Thread-1,54
Thread-0,55
Thread-1,56
Thread-0,57
Thread-1,58
Thread-0,59
Thread-1,60
Thread-0,61
Thread-1,62
Thread-0,63
Thread-1,64
Thread-0,65
Thread-1,66
Thread-0,67
Thread-1,68
Thread-0,69
Thread-1,70
Thread-0,71
Thread-1,72
Thread-0,73
Thread-1,74
Thread-0,75
Thread-1,76
Thread-0,77
Thread-1,78
Thread-0,79
Thread-1,80
Thread-0,81
Thread-1,82
Thread-0,83
Thread-1,84
Thread-0,85
Thread-1,86
Thread-0,87
Thread-1,88
Thread-0,89
Thread-1,90
Thread-0,91
Thread-1,92
Thread-0,93
Thread-1,94
Thread-0,95
Thread-1,96
Thread-0,97
Thread-1,98
Thread-0,99
Thread-1,100
交替打印
一个输入,一个输出
package com.pb.thread.demo3;
/**
*
* @author Denny
* 线程间通讯:
* 其它就是多个线程在操作同一个资源
* 只是操作的动作不同
*
*/
public class Person { private String name;
private int age;
private String gender;
private boolean flag=false; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public boolean getFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
} }
//======================
package com.pb.thread.demo3; public class Input implements Runnable { private Person person; public Input(Person person) {
this.person = person;
} @Override
public void run() {
int x = 0;
while (true) {
synchronized (person) {
if (person.getFlag()) {
try {
person.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (x == 0) {
person.setName("jony");
person.setAge(33);
person.setGender("man");
} else {
person.setName("李丽");
person.setAge(23);
person.setGender("女");
}
x = (x + 1) % 2;
person.setFlag(true);
person.notify();
}
} } public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} }
//=======================
package com.pb.thread.demo3; public class Output implements Runnable { private Person person; public Output(Person person) {
this.person = person;
} @Override
public void run() {
while (true) {
synchronized (person) {
if (!(person.getFlag())) {
try {
person.wait();
} catch (InterruptedException e) { e.printStackTrace();
}
}
System.out.println("姓名:" + person.getName() + "年龄:" + person.getAge() + ",性别:" + person.getGender());
person.setFlag(false);
person.notify();
}
}
} public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} }
//====================
package com.pb.thread.demo3;
/**
*
* @author Denny
*wait(),notify(),notifyAll()
*都使用在同步中,因为要对持胡监视器(锁)的线程操作
*因为只有同步才有锁
*为什么这些操作线程的方法要定义在Object类中呢?
*国为这些方法在操作线程时,都必须要标识它们所操作作线程只有的锁
*只有同一个锁上的被等待,可以被同一个锁上的notify()唤醒
*不可以对不同锁中的线程唤醒
*等待和唤醒必须是同一个锁。
*锁可以是任意对象,可以被任意对象调用的方法在Object中.
*/
public class Test { public static void main(String[] args) {
Person person=new Person();
Input input=new Input(person);
Output output = new Output(person);
Thread t1=new Thread(input);
Thread t2=new Thread(output);
t1.start();
t2.start(); } }
优化以上代码
package com.pb.thread.demo3;
/**
*
* @author Denny
* 线程间通讯:
* 其它就是多个线程在操作同一个资源
* 只是操作的动作不同
*
*/
public class Person { private String name;
private int age;
private String gender;
private boolean flag; public synchronized void setThis(String name,int age,String gender){ if(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name;
this.age=age;
this.gender=gender;
this.flag=true;
notify(); }
public synchronized void getThis(){
if(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("姓名:" + this.name + "年龄:" + this.age + ",性别:" + this.gender);
this.flag=false;
notify();
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public boolean getFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
} }
//====================
package com.pb.thread.demo3; public class Input implements Runnable { private Person person; public Input(Person person) {
this.person = person;
} @Override
public void run() {
int x = 0;
while (true) { if (x == 0) {
person.setThis("jony", 33,"man");
} else {
person.setThis("李丽", 23,"女");
}
x = (x + 1) % 2;
} } public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} }
//========================
package com.pb.thread.demo3; public class Output implements Runnable { private Person person; public Output(Person person) {
this.person = person;
} @Override
public void run() {
while (true) {
person.getThis();
}
} public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} }
//=================
package com.pb.thread.demo3;
/**
*
* @author Denny
*wait(),notify(),notifyAll()
*都使用在同步中,因为要对持胡监视器(锁)的线程操作
*因为只有同步才有锁
*为什么这些操作线程的方法要定义在Object类中呢?
*国为这些方法在操作线程时,都必须要标识它们所操作作线程只有的锁
*只有同一个锁上的被等待,可以被同一个锁上的notify()唤醒
*不可以对不同锁中的线程唤醒
*等待和唤醒必须是同一个锁。
*锁可以是任意对象,可以被任意对象调用的方法在Object中.
*/
public class Test { public static void main(String[] args) {
Person person=new Person();
new Thread(new Input(person)).start();
new Thread(new Output(person)).start(); /* Input input=new Input(person);
Output output = new Output(person);
Thread t1=new Thread(input);
Thread t2=new Thread(output);
t1.start();
t2.start();*/ } }
姓名:李丽年龄:23,性别:女
姓名:jony年龄:33,性别:man
姓名:李丽年龄:23,性别:女
姓名:jony年龄:33,性别:man
姓名:李丽年龄:23,性别:女
姓名:jony年龄:33,性别:man
二、生产者与消费者
2.1、单个生产者和单个消费者
package com.pb.thread.demo4; public class Product {
private String name; private int count; private boolean flag; //生产
public synchronized void set(String name){
if(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name+"..."+count++;
System.out.println(Thread.currentThread().getName()+"---生产者---"+this.name);
this.flag=true;
notify();
}
public synchronized void get(){
if(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"--------消费者------------"+name);
this.flag=false;
notify();
} }
//======================
package com.pb.thread.demo4; public class Producter implements Runnable { private Product product;
public Producter(Product product){
this.product=product;
}
@Override
public void run() {
while(true){
product.set("产品");
} } }
//================
package com.pb.thread.demo4; public class Consumer implements Runnable { private Product product;
public Consumer(Product product){
this.product=product;
}
@Override
public void run() {
while(true){
product.get();
} } }
//================
package com.pb.thread.demo4; public class Test { public static void main(String[] args) {
Product p=new Product();
Producter producter=new Producter(p);
Consumer consumer=new Consumer(p);
Thread t1=new Thread(producter);
Thread t2=new Thread(consumer);
t1.start();
t2.start(); } }
结果:
Thread-0---生产者---产品...20901
Thread-1--------消费者------------产品...20901
Thread-0---生产者---产品...20902
Thread-1--------消费者------------产品...20902
Thread-0---生产者---产品...20903
Thread-1--------消费者------------产品...20903
Thread-0---生产者---产品...20904
Thread-1--------消费者------------产品...20904
Thread-0---生产者---产品...20905
Thread-1--------消费者------------产品...20905
Thread-0---生产者---产品...20906
Thread-1--------消费者------------产品...20906
Thread-0---生产者---产品...20907
Thread-1--------消费者------------产品...20907
Thread-0---生产者---产品...20908
Thread-1--------消费者------------产品...20908
2.2、多个生产者和多个消费者
package com.pb.thread.demo4; public class Product {
private String name; private int count; private boolean flag; //生产
public synchronized void set(String name){
while(flag){ //修改为循环判断
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name+"..."+count++;
System.out.println(Thread.currentThread().getName()+"---生产者---"+this.name);
this.flag=true;
notifyAll(); //修改为notifyAll();
}
public synchronized void get(){
while(!flag){//修改为循环判断
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"--------消费者------------"+name);
this.flag=false;
notifyAll();//修改为notifyAll();
} }
三、JDK 1.5新特性
一、Lock
Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition
对象。
public interface Condition
Condition
将 Object
监视器方法(wait
、notify
和 notifyAll
)分解成截然不同的对象,以便通过将这些对象与任意 Lock
实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock
替代了 synchronized
方法和语句的使用,Condition
替代了 Object 监视器方法的使用。
package com.pb.thread.demo4; import java.util.concurrent.locks.*; public class Product {
private String name; private int count; private boolean flag; Lock lock = new ReentrantLock();// 声明锁对象
// 声明2个condition对象来表示生产者和消费都,如果有多个可以声明多个
// 显示声明
Condition condition_pro = lock.newCondition();// 生产者
Condition condition_con = lock.newCondition(); // 生产
public void set(String name) {
// 加锁
lock.lock();
try {
while (flag) { // 修改为循环判断
condition_pro.await(); // 指定对象锁睡觉
}
this.name = name + "..." + count++;
System.out.println(Thread.currentThread().getName() + "---生产者---" + this.name);
this.flag = true;
// 唤醒指定线程锁
condition_con.signal();// 唤醒消费都线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
} public void get() {
// 加锁
lock.lock();
try {
while (!flag) {
//消费对象锁上
condition_con.await();
}
System.out.println(Thread.currentThread().getName() + "--------消费者------------" + name);
this.flag = false;
//唤醒生产者
condition_pro.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
} } }
四、线程常用方法
4.1、线程常用方法
No.
|
方法名称
|
类型
|
描述
|
1
|
public Thread(Runnable target)
|
构造
|
接收Runnable接口子类对象,实例化Thread对象
|
2
|
public Thread(Runnable target,String name)
|
构造
|
接收Runnable接口子类对象,实例化Thread对象,并设置线程名称
|
3
|
public Thread(String name)
|
构造
|
实例化Thread对象,并设置线程名称
|
4
|
public static Thread currentThread()
|
普通
|
返回目前正在执行的线程
|
5
|
public final String getName()
|
普通
|
返回线程的名称
|
6
|
public final int getPriority()
|
普通
|
发挥线程的优先级
|
7
|
public boolean isInterrupted()
|
普通
|
判断目前线程是否被中断,如果是,返回true,否则返回false
|
8
|
public final boolean isAlive()
|
普通
|
判断线程是否在活动,如果是,返回true,否则返回false
|
9
|
public final void join() throws InterruptedException
|
普通
|
等待线程死亡
|
10
|
public final synchronized void join(long millis) throws InterruptedException
|
普通
|
等待millis毫秒后,线程死亡
|
11
|
public void run()
|
普通
|
执行线程
|
12
|
public final void setName(String name)
|
普通
|
设定线程名称
|
13
|
public final void setPriority(int newPriority)
|
普通
|
设定线程的优先值
|
14
|
public static void sleep(long millis) throws InterruptedException
|
普通
|
使目前正在执行的线程休眠millis毫秒
|
15
|
public void start()
|
普通
|
开始执行线程
|
16
|
public static void yield()
|
普通
|
将目前正在执行的线程暂停,允许其它线程执行
|
17
|
public final void setDaemon(boolean on)
|
普通
|
将一个线程设置成后台运行
|
18
|
public final void setPriority(int newPriority)
|
普通
|
更改线程的优先级
|
五、守护线程和线程优先级
5.1、守护线程-后台资源
setDaemon
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。
该方法必须在启动线程前调用。
该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。
参数:
on - 如果为 true,则将该线程标记为守护线程。
抛出:
IllegalThreadStateException - 如果该线程处于活动状态。
SecurityException - 如果当前线程无法修改该线程。
当前台线程都结束时,后台线程自动结束。
5.2、线程优先级
setPriority
public final void setPriority(int newPriority)更改线程的优先级。
首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException。
在其他情况下,线程优先级被设定为指定的 newPriority 和该线程的线程组的最大允许优先级相比较小的一个。
参数:
newPriority - 要为线程设定的优先级
抛出:
IllegalArgumentException - 如果优先级不在 MIN_PRIORITY 到 MAX_PRIORITY 范围内。
10-----1------------5
static int |
MAX_PRIORITY 线程可以具有的最高优先级。 |
static int |
MIN_PRIORITY 线程可以具有的最低优先级。 |
static int |
NORM_PRIORITY 分配给线程的默认优先级。 |
SecurityException - 如果当前线程无法修改该线程。
getPriority
public final int getPriority()返回线程的优先级。
返回:
该线程的优先级。
六、join线程
作用:阻塞指定的线程等到另一个线程完成以后,再继续执行
package com.pb.thread.demo2; public class MyThread implements Runnable { @Override
public void run() { for(int x=0;x<10;x++){
System.out.println(Thread.currentThread().getName()+"....."+x);
}
} }
//=============
package com.pb.thread.demo2; public class Demo { public static void main(String[] args) { MyThread my=new MyThread();
Thread t1=new Thread(my);
t1.setName("半路加入的线程");
for(int x=0;x<10;x++){
if(x==5){
try {
t1.start();
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
} } System.out.println(Thread.currentThread().getName()+"....."+x);
} } }
结果:
main.....0
main.....1
main.....2
main.....3
main.....4
半路加入的线程.....0
半路加入的线程.....1
半路加入的线程.....2
半路加入的线程.....3
半路加入的线程.....4
半路加入的线程.....5
半路加入的线程.....6
半路加入的线程.....7
半路加入的线程.....8
半路加入的线程.....9
main.....5
main.....6
main.....7
main.....8
main.....9
或者
package com.pb.thread.demo2; public class Test { public static void main(String[] args) { for(int x=0;x<10;x++){
if(x==5){ try {
Thread t1=new Thread(new MyThread(),"半路加入的线程");
t1.start();
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println(Thread.currentThread().getName()+"....."+x);
} } }
七、yield
yield
public static void yield()暂停当前正在执行的线程对象,并执行其他线程。
package com.pb.thread.demo2; public class MyThread implements Runnable { @Override
public void run() { for(int x=0;x<10;x++){ System.out.println(Thread.currentThread().getName()+"....."+x);
Thread.yield();
}
} }
//===========
package com.pb.thread.demo2; public class Test { public static void main(String[] args) {
new Thread(new MyThread(),"线程一").start();
new Thread(new MyThread(),"线程二").start(); } }
八、停止线程
开启多线程,运行代码通常是循环结构
只要控制住循环,就可以让run方法结束。也就是线程结束。
package com.pb.thread.demo4; public class StopThread implements Runnable {
private boolean flag=true;
@Override
public void run() {
while(flag){
System.out.println(Thread.currentThread().getName()+"......run");
} }
public void setChangeFlag(){
this.flag=false;
}
public static void main(String[] args) {
StopThread st=new StopThread();
Thread t1=new Thread(st);
Thread t2=new Thread(st);
t1.start();
t2.start();
int num=0;
while(true){
if(num++==60){
st.setChangeFlag();
break; }
System.out.println(Thread.currentThread().getName()+"===="+num);
}
} }
interrupt
public void interrupt()
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long, int)
方法,或者该类的 join()
、join(long)
、join(long, int)
、sleep(long)
或 sleep(long, int)
方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException
。
package com.pb.thread.demo4; public class StopThread implements Runnable {
private boolean flag = true; @Override
public synchronized void run() {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println(Thread.currentThread().getName() + "......Exception");
flag = false; //设置标识为false
}
System.out.println(Thread.currentThread().getName() + "......run");
} } public void setChangeFlag() {
this.flag = false;
} public static void main(String[] args) {
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t2.start();
int num = 0;
while (true) {
if (num++ == 60) {
//中断状态也就是冻结状态,回到运行状态
t1.interrupt();
t2.interrupt();
break; }
System.out.println(Thread.currentThread().getName() + "====" + num);
}
System.out.println("over");
} }
main====1
main====2
main====3
main====4
main====5
main====6
main====7
main====8
main====9
main====10
main====11
main====12
main====13
main====14
main====15
main====16
main====17
main====18
main====19
main====20
main====21
main====22
main====23
main====24
main====25
main====26
main====27
main====28
main====29
main====30
main====31
main====32
main====33
main====34
main====35
main====36
main====37
main====38
main====39
main====40
main====41
main====42
main====43
main====44
main====45
main====46
main====47
main====48
main====49
main====50
main====51
main====52
main====53
main====54
main====55
main====56
main====57
main====58
main====59
main====60
over
Thread-1......Exception
Thread-1......run
Thread-0......Exception
Thread-0......run
九、sleep();
sleep
public static void sleep(long millis) throws InterruptedException
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
-
参数:
millis
- 以毫秒为单位的休眠时间。抛出:
InterruptedException
- 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。
十、toString
toString
public String toString()
返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
- 返回:
- 该线程的字符串表示形式。
package com.pb.thread.demo4; public class StopThread implements Runnable {
private boolean flag = true; @Override
public synchronized void run() {
while (flag) {
System.out.println(Thread.currentThread().toString()+ "......run");
} } public void setChangeFlag() {
this.flag = false;
} public static void main(String[] args) {
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t2.start();
int num = 0;
while (true) {
if (num++ == 60) {
st.setChangeFlag();
break;
}
System.out.println(Thread.currentThread().toString()+ "====" + num);
}
System.out.println("over");
} }
Thread[Thread-0,5,main]......run
Thread[main,5,main]====1
Thread[Thread-0,5,main]......run
Thread[main,5,main]====2
Thread[Thread-0,5,main]......run
Thread[main,5,main]====3
Thread[Thread-0,5,main]......run
Thread[main,5,main]====4
Thread[main,5,main]====5
Thread[main,5,main]====6
Thread[main,5,main]====7
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====8
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====9
Thread[Thread-0,5,main]......run
Thread[main,5,main]====10
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====11
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====12
Thread[main,5,main]====13
Thread[main,5,main]====14
Thread[main,5,main]====15
Thread[main,5,main]====16
Thread[Thread-0,5,main]......run
Thread[main,5,main]====17
Thread[main,5,main]====18
Thread[main,5,main]====19
Thread[main,5,main]====20
Thread[main,5,main]====21
Thread[main,5,main]====22
Thread[main,5,main]====23
Thread[main,5,main]====24
Thread[main,5,main]====25
Thread[main,5,main]====26
Thread[main,5,main]====27
Thread[main,5,main]====28
Thread[main,5,main]====29
Thread[main,5,main]====30
Thread[main,5,main]====31
Thread[main,5,main]====32
Thread[main,5,main]====33
Thread[main,5,main]====34
Thread[main,5,main]====35
Thread[main,5,main]====36
Thread[main,5,main]====37
Thread[main,5,main]====38
Thread[main,5,main]====39
Thread[main,5,main]====40
Thread[main,5,main]====41
Thread[main,5,main]====42
Thread[main,5,main]====43
Thread[main,5,main]====44
Thread[main,5,main]====45
Thread[main,5,main]====46
Thread[main,5,main]====47
Thread[main,5,main]====48
Thread[main,5,main]====49
Thread[main,5,main]====50
Thread[main,5,main]====51
Thread[main,5,main]====52
Thread[main,5,main]====53
Thread[main,5,main]====54
Thread[main,5,main]====55
Thread[main,5,main]====56
Thread[main,5,main]====57
Thread[main,5,main]====58
Thread[main,5,main]====59
Thread[main,5,main]====60
over
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====1
Thread[Thread-0,5,main]......run
Thread[main,5,main]====2
Thread[Thread-0,5,main]......run
Thread[main,5,main]====3
Thread[Thread-0,5,main]......run
Thread[main,5,main]====4
Thread[main,5,main]====5
Thread[main,5,main]====6
Thread[main,5,main]====7
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====8
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====9
Thread[Thread-0,5,main]......run
Thread[main,5,main]====10
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====11
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run
Thread[main,5,main]====12
Thread[main,5,main]====13
Thread[main,5,main]====14
Thread[main,5,main]====15
Thread[main,5,main]====16
Thread[Thread-0,5,main]......run
Thread[main,5,main]====17
Thread[main,5,main]====18
Thread[main,5,main]====19
Thread[main,5,main]====20
Thread[main,5,main]====21
Thread[main,5,main]====22
Thread[main,5,main]====23
Thread[main,5,main]====24
Thread[main,5,main]====25
Thread[main,5,main]====26
Thread[main,5,main]====27
Thread[main,5,main]====28
Thread[main,5,main]====29
Thread[main,5,main]====30
Thread[main,5,main]====31
Thread[main,5,main]====32
Thread[main,5,main]====33
Thread[main,5,main]====34
Thread[main,5,main]====35
Thread[main,5,main]====36
Thread[main,5,main]====37
Thread[main,5,main]====38
Thread[main,5,main]====39
Thread[main,5,main]====40
Thread[main,5,main]====41
Thread[main,5,main]====42
Thread[main,5,main]====43
Thread[main,5,main]====44
Thread[main,5,main]====45
Thread[main,5,main]====46
Thread[main,5,main]====47
Thread[main,5,main]====48
Thread[main,5,main]====49
Thread[main,5,main]====50
Thread[main,5,main]====51
Thread[main,5,main]====52
Thread[main,5,main]====53
Thread[main,5,main]====54
Thread[main,5,main]====55
Thread[main,5,main]====56
Thread[main,5,main]====57
Thread[main,5,main]====58
Thread[main,5,main]====59
Thread[main,5,main]====60
over
Thread[Thread-0,5,main]......run
十一、匿名内部类实现多线程
package com.pb.thread.demo4;
/*
* 匿名内部类实现多线程
*/
public class ThreadTest { public static void main(String[] args) {
//线程对象
new Thread(){
public void run(){
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName()+".........."+x);
}
}
}.start();
//Runnable 接口
Runnable r=new Runnable(){
public void run(){
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName()+".........."+x);
}
}
};
//启动线程
new Thread(r).start();
} }
基础学习day12--多线程一线程之间的通信和常用方法的更多相关文章
- Java多线程编程-线程之间的通信
转载自:这里 学习了基础的线程知识 看到了 线程之间的通信 线程之间有哪些通信方式呢? 1.同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. public ...
- java并发学习--第六章 线程之间的通信
一.等待通知机制wait()与notify() 在线程中除了线程同步机制外,还有一个最重要的机制就是线程之间的协调任务.比如说最常见的生产者与消费者模式,很明显如果要实现这个模式,我们需要创建两个线程 ...
- Java多线程中线程间的通信
一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...
- Java学习笔记46(多线程三:线程之间的通信)
多个线程在处理同一个资源,但是线程的任务却不相同,通过一定的手段使各个线程能有效地利用资源, 这种手段即:等待唤醒机制,又称作线程之间的通信 涉及到的方法:wait(),notify() 示例: 两个 ...
- Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...
- iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信
一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- vc 基于对话框多线程编程实例——线程之间的通信
vc基于对话框多线程编程实例——线程之间的通信 实例:
随机推荐
- 禁用iPhone手机浏览器上给电话号码自动加上的link样式
iPhone手机上的浏览器(如Safari),在解析网页的时候会自动给 像是电话号码的数字 加上link样式. 可以添加下面的meta禁用掉这个功能. // //
- 快速清除文件夹svn版本控制信息
将下面内容另存为clear.bat文件,在有版本控制的目录执行即可 @echo On @Rem 清除SVN版本控制信息 @for /r . %%a in (.) do @if exist " ...
- 测试lua的效率
这几天粗略的测试了一下lua的效率!首先声明这个测试很有针对性,大部分是针对游戏中的使用,而绝非lua的整体性效率(这个测试我不会),lua构建的上层逻辑中,大概使用的语句不太多,for,迭代,调用C ...
- 通俗易懂的ListView讲解(Adapter、图、实例)
2016/4/5 17:22] 之前写listview其实写了很多次,但好像还是模模糊糊的感觉,直到今天准备写tab的时候被告诉说原理有像的地方,于是我就先来分析整理一下listview好了 先来 ...
- 点餐系统mealsystem.sql
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50162 Source Host : ...
- sprint个人总结+读书博客
读书感想: 第8章讲了需求分析,在我的日常软件编写中,肯定需要需求分析的,一个没有需求的软件,编写出来也没有什么意义,只能是丢在一个角落里发霉.需求有各种各样,要怎样才能满足客户的需求呢,那就要 ...
- JS 生成26个大小写字母
主要用到 str.charCodeAt()和 String.fromCharCode()方法 -->使用 charCodeAt() 来获得字符串中某个具体字符的 Unicode 编码. --&g ...
- JS 获取 本周、本月、本季度、本年、上月、上周、上季度、去年
工具类定义: /** * 日期范围工具类 */ var dateRangeUtil = (function () { /*** * 获得当前时间 */ this.getCurrentDate = fu ...
- 周末web前端练习
在 CSS 样式定义中,以下哪种 RGB 颜色值是 Web 安全色? A]#111111B]#222222C]#333333D]#444444 答案:http://hovertree.com/ti ...
- C#开发中可能会用到的一些小贴士(转)
转至http://www.cnblogs.com/Ebony-Ivory/p/4380106.html C#篇: 1.目标平台的选择 64位操作系统在编译VS里的程序时,根据需要设置项目属性的“目标平 ...