----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
线程间的通信:其实就是多个线程在操作同一个资源,只是操作的动作不同.
package 多线程;
public class Demo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Res r = new Res();
Input i = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(i);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}
class Res{
String name;
String sex;
}
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run(){
int x = 0;
while(true){
r.name = "Mike";
r.sex = "man";
r.name = "丽丽";
r.sex = "女";
if(x==0){
r.name = "Mike";
r.sex = "man";
}
else{
r.name = "丽丽";
r.sex = "女";
}
x = (x+1)%2;
}
}
}
class Output implements Runnable{
Res r = new Res();
Output(Res r){
this.r = r;
}
public void run(){
while(true){
System.out.println(r.name+""+r.sex);
}
}
}
打印结果出现 丽丽man,Mike女.即出现安全问题
package 多线程;
public class Demo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Res r = new Res();
Input i = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(i);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}
class Res{
String name;
String sex;
}
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run(){
int x = 0;
while(true){
synchronized (Input.class) {
if(x==0){
r.name = "Mike";
r.sex = "man";
}
else{
r.name = "丽丽";
r.sex = "女";
}
}
x = (x+1)%2;
}
}
}
class Output implements Runnable{
Res r = new Res();
Output(Res r){
this.r = r;
}
public void run(){
while(true){
synchronized(Input.class/*r或者Output.class*/){
System.out.println(r.name+""+r.sex);
}
}
}
}
等待唤醒机制(wait()与notify())
Wait(),notify(),notifyAll():都使用在同步中,因为要对持有监视器(锁)的线程操作.所以要使用在同步中,因为只有同步才具有锁.
为什么这些操作线程的方法要定义object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁.只有同一个锁上的被等待线程,可以被同一个锁上notify换醒.不可以对不同锁中的线程进行唤醒.
也就是说,等待与唤醒必须是同一个锁.
而锁是任意对象,所以可以被任意对象调用的方法定义Object类中
package 多线程;
public class Demo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Res r = new Res();
Input i = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(i);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}
class Res{
String name;
String sex;
boolean flag = false;
}
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run(){
int x = 0;
while(true){
synchronized (r) {
if(r.flag)
try{r.wait();}catch(Exception e){}
if(x==0){
r.name = "Mike";
r.sex = "man";
}
else{
r.name = "丽丽";
r.sex = "女";
}
x = (x+1)%2;
r.flag = true;
r.notify();
}
}
}
}
class Output implements Runnable{
private Res r;
Output(Res r){
this.r = r;
}
public void run(){
while(true){
synchronized(r){
if(!r.flag)
try{r.wait();}catch(Exception e){}
System.out.println(r.name+""+r.sex);
r.flag = false;
r.notify();
}
}
}
}
代码优化:
package 多线程;
public class Demo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Res r = new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
/*Input i = new Input(r);
Output o = new Output(r);
Thread t1 = new Thread(i);
Thread t2 = new Thread(o);
t1.start();
t2.start();*/
}
}
class Res{
private String name;
private String sex;
boolean flag = false;
public synchronized void set(String name,String sex){
if(flag)
try{this.wait();}catch(Exception e){}
this.name=name;
this.sex = sex;
flag = true;
this.notify();
}
public synchronized void out(){
if(!flag)
try{this.wait();}catch(Exception e){}
System.out.println(name+"......."+sex);
this.flag = false;
this.notify();
}
}
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run(){
int x = 0;
while(true){
/*synchronized (r) {
if(r.flag)
try{r.wait();}catch(Exception e){}*/
if(x==0)
r.set("Mike","man");
else
r.set("丽丽","女");
x = (x+1)%2;
/*
r.flag = true;
r.notify();*/
}
}
}
class Output implements Runnable{
private Res r;
Output(Res r){
this.r = r;
}
public void run(){
while(true){
r.out();
}
}
}
生产者消费者
public class Demo2 {
/**
* @param args
*/
public static void main(String[] args) {
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
t1.start();
t2.start();
}
}
class Resource{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name){
if(flag)
try{wait();}catch(Exception e){}
this.name = name+".."+count++;
System.out.println(Thread.currentThread().getName()+"..生产者"+this.name);
flag = true;
this.notify();
}
public synchronized void out(){
if(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"..消费者"+this.name);
flag = false;
this.notify();
}
}
class Producer implements Runnable{
private Resource res;
Producer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.set("商品");
}
}
}
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
}
若有多条线程同时在生产和消费.循环必须用while,唤醒必须用notifyAll();
public class Demo2 {
/**
* @param args
*/
public static void main(String[] args) {
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name){
while(flag)
try{wait();}catch(Exception e){}
this.name = name+".."+count++;
System.out.println(Thread.currentThread().getName()+"..生产者"+this.name);
flag = true;
this.notifyAll();
}
public synchronized void out(){
while(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"..消费者"+this.name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable{
private Resource res;
Producer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.set("商品");
}
}
}
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res) {
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
}
停止线程:用run方法结束,开启多线程运行,运行代码通常是循环结构.只要控制住循环,就可以让run方法就是,也就是线程结束.
public class Demo3 {
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.changeFlag();
break;
}
System.out.println(Thread.currentThread().getName()+"..."+num);
}
}
}
class StopThread implements Runnable{
private boolean flag = true;
public void run(){
while(flag){
System.out.println(Thread.currentThread().getName()+"...run");
}
}
public void changeFlag(){
flag = false;
}
}
特殊情况:当线程处于冻结状态.就不会读取到标记,那么线程就不会结束.
解决办法(interrupt):当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除.强制让线程恢复到运行状态中来.这样就可以操作标记让线程结束.
public class Demo3 {
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.changeFlag();
t1.interrupt();
t2.interrupt();
break;
}
System.out.println(Thread.currentThread().getName()+"..."+num);
}
}
}
class StopThread implements Runnable{
private boolean flag = true;
public synchronized void run(){
while(flag){
try{
wait();
}catch(InterruptedException e){
System.out.println(Thread.currentThread().getName()+"...");
flag = false;
}
System.out.println(Thread.currentThread().getName()+"...run");
}
}
public void changeFlag(){
flag = false;
}
Join方法:可以用来临时加入线程执行.当A线程执行到了B线程的.join()方法时,A就好等待.等B线程都执行完,A线程才会执行.
public class Demo4 {
public static void main(String[] args)throws Exception {
demo d = new demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();
t2.start();
for(int x=0;x<80;x++ ){
System.out.println("main..."+x);
}
System.out.println("over");
}
}
class demo implements Runnable{
public void run(){
for(int x=0;x<70;x++){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
}
}