一、线程之间的通信

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

ConditionObject 监视器方法(waitnotifynotifyAll)分解成截然不同的对象,以便通过将这些对象与任意 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()

返回该线程的字符串表示形式,包括线程名称、优先级和线程组。

覆盖:
Object 中的 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--多线程一线程之间的通信和常用方法的更多相关文章

  1. Java多线程编程-线程之间的通信

    转载自:这里 学习了基础的线程知识 看到了 线程之间的通信 线程之间有哪些通信方式呢? 1.同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. public ...

  2. java并发学习--第六章 线程之间的通信

    一.等待通知机制wait()与notify() 在线程中除了线程同步机制外,还有一个最重要的机制就是线程之间的协调任务.比如说最常见的生产者与消费者模式,很明显如果要实现这个模式,我们需要创建两个线程 ...

  3. Java多线程中线程间的通信

    一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...

  4. Java学习笔记46(多线程三:线程之间的通信)

    多个线程在处理同一个资源,但是线程的任务却不相同,通过一定的手段使各个线程能有效地利用资源, 这种手段即:等待唤醒机制,又称作线程之间的通信 涉及到的方法:wait(),notify() 示例: 两个 ...

  5. Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  6. iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信

    一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...

  7. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

  8. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  9. vc 基于对话框多线程编程实例——线程之间的通信

     vc基于对话框多线程编程实例——线程之间的通信 实例:

随机推荐

  1. emacs工程管理,cedet ede插件自动构建Make,Automake

    鉴于自己一直都是在做客户端开发方面的工作,服务端很多知识都随着时间淡忘了,最近有一个计划,用一些时间补一下基础.所以早上很早就起床,花了一点时间大致浏览了一下BSD socket的相关API,然后用G ...

  2. 文本框不够长,显示“XXX...”

    WPF: How to make the TextBox/TextBlock/Label show "xxx..." if the text content too long? 设 ...

  3. Knockout 新版应用开发教程之"text"绑定

    目的 DOM元素显示文本的值是你传递的参数,前提是text先绑定到该元素上 典型的常用元素 <span>或者<em>习惯性的用来显示文本,但是在技术上来说你可以用任何元素的. ...

  4. ruby -- 基础学习(六)时间计算

    计算下一天的这个时刻, # 比如"2013-8-16 18:45:12" 的下一天的这个时刻 “2013-8-17 18:45:12” Time.now + 1.day 如果想得到 ...

  5. 使用的 SQL Server 版本不支持数据类型“datetime2”的错误解决方法

    THE VERSION OF SQL IN USE DOES NOT SUPPORT DATATYPE ‘DATETIME2′ 主要错误原因,在使用ado.net entity的时候,entity使用 ...

  6. 编辑器之神VIM 总结(一) 基础部分

     版本号 说明 作者 日期  1.0  vim基础知识 Sky Wang 2013/06/19       概要 vim和emacs,一个是编辑器之神,一个是神一样的编辑器.他们被称是UNIX系统下的 ...

  7. 【干货分享】Google 的设计准则,素材和资源

    在谷歌,他们说, “专注于用户,所有其它的就会水到渠成 ”.他们遵循设计原则,寻求建立让用户惊喜的用户体验.谷歌一直挑战自己,为他们的用户创造一种视觉语言,综合优秀设计的经典原则和创新.谷歌设计规范是 ...

  8. Android 学习笔记 Service服务与远程通信...(AIDL)

    PS:这一章节看的我有几分迷茫,不是很容易理解...不过还好总算是明白了一大半了...基本的迷惑是解决了... 学习内容: 1.跨应用启动服务... 2.跨应用绑定服务... 3.跨应用实现通信... ...

  9. .NET框架面向对象分层的个人想理

    简单.层次清晰不要过度优化,接口这玩意儿就是个双刃剑,玩好了解藕,玩不好自找麻烦,好的代码永远都是傻瓜都能看懂的. 总结成以下几条: 公用层 代码公用并且与第三方DLL和业务逻辑无关的 独立出来 逻辑 ...

  10. SQL年月日方面的查询信息

    这是计算一个月第一天的SQL 脚本:   SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) --当月的第一天 SELECT DATEADD(mm, DAT ...