基础学习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基于对话框多线程编程实例——线程之间的通信 实例:
随机推荐
- JSON数据行转列的应用
背景 先说说为什么要弄什么行转列. 时间 类别 费用 2014-07-08 电费 120 2014-07-08 水费 23 2014-07-09 电费 44 2014-07-09 水费 77 ...
- 固态硬盘寿命实测让你直观SSD寿命!--转
近年来,高端笔记本及系列上网本越来越多的采用固态硬盘来提升整机性能,尽管众所周知固态硬盘除 了在正常的使用中带来更快速度的体验外,还具有零噪音.不怕震动.低功耗等优点,但大家对固态硬盘的寿命问题的担忧 ...
- Node.js建站笔记-使用react和react-router取代Backbone
斟酌之后,决定在<嗨猫>项目中引入react,整体项目偏重spa模式,舍弃部分server端的模板渲染,将一部分渲染工作交给前端react实现. react拥有丰富的组件,虽然不如Back ...
- SQL Server里等待统计(Wait Statistics)介绍
在今天的文章里我想详细谈下SQL Server里的统计等待(Wait Statistics),还有她们如何帮助你立即为什么你的SQL Server当前很慢.一提到性能调优,对我来说统计等待是SQL S ...
- SystemTap知识(一)
SystemTap是一个系统的跟踪探测工具.它能让用户来跟踪和研究计算机系统在底层的实现. 安装SystemTap需要为你的系统内核安装-devel,-debuginfo,-debuginfo-com ...
- IOS开发中设置控件内容对齐方式时容易混淆的几个属性
IOS开发中四个容易混淆的属性: 1. textAligment : 文字的水平方向的对齐方式 1> 取值 NSTextAlignmentLeft = 0, // 左对齐 NST ...
- [Architect] Abp 框架原理解析(4) Validation
本节目录 介绍 DataAnnotations ICustomValidate IShouldNormalize 实现Abp Validation 介绍 Abp中在Application层集成了val ...
- Spring基础——在Spring Config 文件中配置 Bean
一.基于 XML 的 Bean 的配置——通过全类名(反射) <bean <!-- id: bean 的名称在IOC容器内必须是唯一的若没有指定,则自动的将全限定类名作为 改 bean 的 ...
- WCF 4.0 使用说明
WCF 4.0开发说明,工具VS2013 ,IIS,使用http协议 打开VS2013,新建项目Visual C#>Web>Asp.NET Web应用程序,添加相关引用: System.S ...
- C#检查标准图幅编号
/// <summary> /// 检查是否为标准图幅编号 /// </summary> /// <param name="MapNumber"> ...