线程间的通信
两个或两个以上的线程处理同一个资源,处理的动作是不一样的。
这样就需要将不同的动作代码放到不同的run方法中,run方法要封装到单独的类中。
使用方法:
同步中使用object类的方法
wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。
notify():唤醒等待的线程,唤醒第一个
notifyAll():唤醒所以等待的线程。
实例,生产者和消费者。
分析:
生产者-消费者问题是多线程同步处理的典型问题
有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品
这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。
-
线程B写一次,线程A读一次
-
在某个时候线程B运行速度比较快,在线程A未读取上一个数据之前,B就写了第二次数据,造成数据遗漏。
-
在某个时候线程A运行速度比较快,它读完一次数据之后,线程B还没来得及写,线程A又来读第二次。结果线程A读不到数据,导致运行出错。
-
线程B正在写数据时,线程A也来读取数据,这时可能线程B还没将数据写完,线程A将数据读走,导致程序出错。
1.搭架子
package com.csdn;
public class ProAndSell {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
//资源类
class Resource{
String name;
String sex;
}
//生产类
class Product implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
}
}
//销售类
class Sell implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
}
}
2.填充代码
package com.csdn;
public class ProAndSell {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Product pro = new Product(r);
Sell se = new Sell(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(se);
t1.start();
t2.start();
}
}
//资源类
class Resource{
String name;
String sex;
}
//生产类
class Product implements Runnable{
private Resource r;
public Product(Resource r){
this.r = r;
}
@Override
public void run() {
int x = 0;
while(true){
if(x == 0){
r.name = "张三";
r.sex = "男";
} else {
r.name = "lisi";
r.sex = "nv";
}x=(x+1)%2;
}
}
}
//销售类
class Sell implements Runnable{
private Resource r;
public Sell(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
System.out.println(r.name+"...."+r.sex);
}
}
}
两个线程,首先输入的线程生产出张三,男,CPU资源没有切换给输出线程,输入还拥有CPU资源,接着生产,生产张三,CPU资源切换给输出,出现张三.......nv
3.封锁,同步代码块
package com.csdn;
public class ProAndSell {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Product pro = new Product(r);
Sell se = new Sell(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(se);
t1.start();
t2.start();
}
}
//资源类
class Resource{
String name;
String sex;
}
//生产类
class Product implements Runnable{
private Resource r;
Object obj = new Object();
public Product(Resource r){
this.r = r;
}
@Override
public void run() {
int x = 0;
while(true){
synchronized (obj) {
if(x == 0){
r.name = "张三";
r.sex = "男";
} else {
r.name = "lisi";
r.sex = "nv";
}
}
x=(x+1)%2;
}
}
}
//销售类
class Sell implements Runnable{
private Resource r;
Object obj = new Object();
public Sell(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
synchronized (obj) {
System.out.println(r.name+"...."+r.sex);
}
}
}
}
还是有错误,是以为上锁的时候是两把锁
4.让生产者和消费者有共同的锁
package com.csdn;
public class ProAndSell {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Product pro = new Product(r);
Sell se = new Sell(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(se);
t1.start();
t2.start();
}
}
//资源类
class Resource{
String name;
String sex;
}
//生产类
class Product implements Runnable{
private Resource r;
public Product(Resource r){
this.r = r;
}
@Override
public void run() {
int x = 0;
while(true){
synchronized (r) {
if(x == 0){
r.name = "张三";
r.sex = "男";
} else {
r.name = "lisi";
r.sex = "nv";
}
}
x=(x+1)%2;
}
}
}
//销售类
class Sell implements Runnable{
private Resource r;
public Sell(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
synchronized (r) {
System.out.println(r.name+"...."+r.sex);
}
}
}
}
线程的随机性
5.线程的通信
package com.csdn;
public class ProAndSell {
public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Product pro = new Product(r);
Sell se = new Sell(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(se);
t1.start();
t2.start();
}
}
//资源类
class Resource{
String name;
String sex;
boolean f;
}
//生产类
class Product implements Runnable{
private Resource r;
public Product(Resource r){
this.r = r;
}
@Override
public void run() {
int x = 0;
while(true){
synchronized (r) {
if(r.f)
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(x == 0){
r.name = "张三";
r.sex = "男";
} else {
r.name = "lisi";
r.sex = "nv";
}
r.f = true;
r.notify();
}
x=(x+1)%2;
}
}
}
//销售类
class Sell implements Runnable{
private Resource r;
public Sell(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
synchronized (r) {
if(!r.f)
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(r.name+"...."+r.sex);
r.f = false;
r.notify();
}
}
}
}
6.优化代码
package com.csdn;
public class ProAndSell {
public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Product pro = new Product(r);
Sell se = new Sell(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(se);
t1.start();
t2.start();
}
}
//资源类
class Resource{
private String name;
private String sex;
private boolean f;
public synchronized void set(String name, String sex){
if(f)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.sex = sex;
f=true;
notify();
}
public synchronized void out(){
if(!f)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+"...."+sex);
f = false;
notify();
}
}
//生产类
class Product implements Runnable{
private Resource r;
public Product(Resource r){
this.r = r;
}
@Override
public void run() {
int x = 0;
while(true){
if(x == 0){
r.set("张三", "男");
} else {
r.set("lisi", "nv");
}
x=(x+1)%2;
}
}
}
//销售类
class Sell implements Runnable{
private Resource r;
public Sell(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
r.out();
}
}
}
三段代码并行
package com.csdn;
public class ThreadDemo6 {
/**
* @param args
*/
public static void main(String[] args) {
new Thread(){
public void run(){
for(int i=0;i<100;i++){
System.out.println("a="+i);
}
}
}.start();
for(int i=0;i<100;i++){
System.out.println("b="+i);
}
Runnable r=new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("c="+i);
}
}
};
new Thread(r).start();
}
}
分享到:
相关推荐
Java多线程实例,是学习java多线程的好方法
详细介绍的JAVA的多线程程序设计
实现多线程TCP传输,同时分成发送方和接受方
黑马程序员_张孝祥_Java多线程与并发库,视频+代码+资料
c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程...
Java中的多线程结构请大家观看不足的地方请指教,大家可以一语既出的观看和指导。
多线程下载,随便做的,有一定的局限性,仅供参考
1.讲解了Java多线程的基础, 包括Thread类的核心API的使用。2.讲解了在多线程中对并发访问的控制, 主要就是synchronized的使用, 由于此关键字在使用上非常灵活, 所以书中用了很多案例来介绍此关键字的使用, 为...
一个简单记录java多线程下变量共享问题,分析多线程内部运行
串口通信的实现,编程环境为C#,实现技术采用了多线程方式
java的打字程序,包含了多线程编写的练习和Applet的编程练习。
实现了多线程电梯的调度算法(3部电梯统一进行调度)
张孝祥Java多线程与并发库高级应用学习笔记,很经典的学习多线程和并发的资料。张孝祥Java多线程讲义笔记由张孝祥亲自整理,很实用的。
smoker_java多线程_源码.zip
多线程TCP连接,用java实现 多线程TCP连接,用java实现
JAVA解惑_Java多线程_JS_HTML5.zip
基于java多线程的通信,类似QQ,包括客户端和服务端。
_Java多线程编程详解.doc
多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字和示例来介绍与java线程相关的设计模式理念
Java_servlet多线程 Java_servlet多线程