/*
线程通信
多线程操作同一个资源,一个赋值一个取值,数据的错乱,使用同步技术,发现数据安全问题,还是没解决
同步中的程序都是线程的共享数据吗
同步中的锁是同一个吗
使用的是线程的等待与唤醒机制,实现输入输出的间隔效果,复杂在于解决思想
等待与唤醒的方法 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的执行权礼让出去
写在执行的线程中就可以了,不需要对象调用
*/
线程通信
多线程操作同一个资源,一个赋值一个取值,数据的错乱,使用同步技术,发现数据安全问题,还是没解决
同步中的程序都是线程的共享数据吗
同步中的锁是同一个吗
使用的是线程的等待与唤醒机制,实现输入输出的间隔效果,复杂在于解决思想
等待与唤醒的方法 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的执行权礼让出去
写在执行的线程中就可以了,不需要对象调用
*/