黑马程序员_多线程2

来源:互联网 发布:qq音乐数据库 api接口 编辑:程序博客网 时间:2024/05/18 01:39
/*
线程通信
  多线程操作同一个资源,一个赋值一个取值,数据的错乱,使用同步技术,发现数据安全问题,还是没解决
同步中的程序都是线程的共享数据吗
同步中的锁是同一个吗
     使用的是线程的等待与唤醒机制,实现输入输出的间隔效果,复杂在于解决思想
   等待与唤醒的方法  Object类的方法 wait  notify 程序出现了异常
     java.lang.IllegalMonitorStateException
     导致异常的原因,wait()  notify()导致的异常,使用等待与唤醒,必须有锁的支持,wait,notify必须写在同步中,必须用锁对象调用
线程通信中的方法wait,notify为什么写在Object类中
  锁有关系,同步中的锁是一个对象,而是什么对象,不确定的,因此方法写在了顶层的父类中,无论哪一个对象作为锁,都可以使用线程的方法




*/
/*
 * 多线程的通信
 * 输入线程赋值
 * 输出线程打印值
 * 
 */
//资源对象
class Resource{
String name;
String sex;
boolean b = false;//定义,b=true,赋值完成,b = false打印完成
}
//定义输入线程
class Input implements Runnable{
Resource r  ;
Input(Resource r){this.r = r;}
public void run(){
int x = 0 ;
while(true){
synchronized(r){
//输入线程,判断b的值,如果是真,等待
if(r.b==true)
try{r.wait();}catch(Exception e){}
if(x%2==0){
r.name = "张三";
r.sex = "男";
}else{
r.name = "lisi";
r.sex = "nv";
}
x++;
//标记改成true
r.b = true;
//唤醒输出线程
r.notify();
}
}
}
}
//定义输出线程,打印变量值
class Output implements Runnable{
Resource r ;
Output(Resource r){this.r = r;}
public void run(){
while(true){
synchronized(r){
if(r.b==false)
try{r.wait();}catch(Exception e){}
System.out.println(r.name+"..."+r.sex);
 r.b = false;
 r.notify();
}
}
}
}
public class ThreadDemo6 {
public static void main(String[] args) {
Resource  r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread tin = new Thread(in);
Thread tout = new Thread(out);
tin.start();
tout.start();
}
}
/*
wait方法和sleep方法有什么区别
  Thread类的静态方法sleep 无论线程休眠多长时间,线程不丢失对象监视器,不放锁
  wait方法,线程将发布对象监视器,释放锁,被唤醒后,从新获取锁后,才能运行


*/
/*
多线程的通信,多生产者和多消费者
  notify唤醒线程的时候,往往是最先等待的线程
  线程从哪里等待,从哪里唤醒
在1.5版本的时候,出现了一个新的锁
   新的锁,替换现在的同步机制 java.util.concurrent.locks包中,Lock接口
   Lock接口,替换的同步,更加广泛和灵活的锁定操作
   接口中的方法,lock()获取锁  unlock() 释放锁
   synchronize(this){ == 获取锁


   } == 释放锁
  找子类 ReentrantLock 接口指向实现类的方式


  既然同步没有了,this锁也就不存在了,替代品 java.util.concurrent.locks.Condition接口
  Condition接口中的方法
   await() == wait()
   signal() == nofify()
   signalAll() == notifyAll()
实现唤醒对方的一个线程,实现步骤:
导包
获取锁对象,Lock接口的实现类对象ReentrantLock
Lock接口中的方法lock()  unlock()替换同步机制
获取Condition对象,对线程进行分组管理,使用Lock接口中的方法new Condition获取接口的实现类对象
利用Condition对象中的方法await signal实现等待与唤醒


*/
import java.util.concurrent.locks.*;
class Product {
private String name;//品名
private int count = 0 ;//计数器
private boolean b = false;

//获取Lock接口的实现类对象,获取锁
private Lock lock = new ReentrantLock();
private Condition pro = lock.newCondition();
private Condition cus = lock.newCondition();

//生产方法
public  void set(String name){
lock.lock();
while(b){
try{pro.await();}catch(Exception e){}
}
this.name = name +".."+count++;//this.name成员变量,品名+计数器
System.out.println(Thread.currentThread().getName()+" 生产第.."+this.name);
b = true;
cus.signal();
lock.unlock();
}
//消费方法
public  void get(){
lock.lock();
while(!b){
try{cus.await();}catch(Exception e){}
}
System.out.println(Thread.currentThread().getName()+" 消费第......"+this.name);
b = false;
pro.signal();
lock.unlock();
}
}
//定义生产者线程
class Pro implements Runnable{
private Product p ;
Pro(Product p){this.p = p;}
public void run(){
while(true)
p.set("黄金");
}
}
//定义消费线程
class Cus implements Runnable{
private Product p ;
Cus(Product p ){this.p = p;}
public void run(){
while(true)
p.get();
}
}
public class ThreadLock {
public static void main(String[] args) {
Product p = new Product();
Pro pro = new Pro(p);
Cus cus = new Cus(p);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(pro);

Thread t4 = new Thread(cus);
Thread t5 = new Thread(cus);
Thread t6 = new Thread(cus);
Thread t7 = new Thread(cus);

t0.start();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
}
}
/*线程的停止方式
  Thread类方法stop过时,不用了
  结束线程,终止run方法的执行
第一种,是改变循环变量
第二种,利用异常  interrupt
*/
class Stop implements Runnable{
private boolean flag = true;
public void run(){
while(flag){
synchronized(this){
try{
this.wait();
}catch(Exception e){
System.out.println("线程被打了");
   flag = false;
}
System.out.println("run...");
}
}
}
public void setFlag(boolean flag){
this.flag = flag;
}
}
public class ThreadStopDemo {
public static void main(String[] args) {
Stop s = new Stop();
Thread t = new Thread(s);
t.start();
for(int x = 0 ; x < 100 ; x++){
if(x == 99)
//s.setFlag(false);
t.interrupt();
System.out.println("main..."+x);
}
}
}
/*
定时任务
  没到一个指定的时候,程序自动的去完成一个功能
  定时器. java.util.Timer实现定时运行程序
  Timer类的够造方法,设置成不是守护线程,构造方法传递false
  schedule()方法,定时运行的方法,三个参数 ,执行的代码,开始时间,间隔,毫秒


Thread类的toString()方法,优先级
  toString()方法,名字,优先级,线程组
  优先级,设置的优先级三个级别 最低1,默认5,最高10
  Thread方法 void setPriority(int )设置优先级


join方法,yield方法
  join方法,等待该线程终止
  t0线程,t1线程,main线程,t0调用join方法
  t0先执行完毕,t1 main进行CPU的资源争夺


  static yield方法,线程的让步,线程把CPU的执行权礼让出去
  写在执行的线程中就可以了,不需要对象调用


*/
0 0
原创粉丝点击