多线程问题的思路与处理方式。

一般:我们把共享资源拿出来,,把各种对共享资源操作的方法与资源封装在一起,在写方法的时候,我们就要考虑到完整性和顺序性。

加锁,只是为了让一个线程能够把操作共享数据的语句连续执行完。保证完整性。

加锁的两种方式:同步synchronized   Lock lock=new ReetrentLock();

如果涉及到顺序问题,在锁里边,借助资源的flag,使用用wait,notify或者await  singnal。

总之,一想到多线程,就把操作的共享资源与操作共享资源的方法封装成一个类,对操作共享数据的方法加锁。

如果多线程涉及到顺序问题,就要在(方法)锁里边操作(await,singnal,,,)。保证顺序。

下边是详细的叙述:

多个线程,,功能相同,就像卖票一样,Thread(一样)

这个时候的安全问题:是线程对共享数据操作的不完整性。

对操作共享数据的语句加锁,保证线程操作数据的完整性。

这种情况只要一把锁。

class Count

{

private int sum;

public synchronized void add(int n)

{

sum=sum+n;

try{Thread.sleep(10);}catch(Exception e){}

System.out.println("sum"+sum);

}

}

class Person implements Runnable

{

private Count b=new Count();

public void run()

{

for(int x=0;x<3;x++)

{

b.add(100);

}

}

}

class  CountDemo

{

public static void main(String[] args)

{

Person p=new Person();

Thread t1=new Thread(p);

Thread t2=new Thread(p);

t1.start();

t2.start();

}

}

多个线程功能不同(执行的代码不一样),但还是在操作共享数据。

一般,把这些操作操作共享数据的语句封装成方法,与共享数据形成一个类。

1.对不同线程操作共享数据的顺序无要求:::对各个线程的执行代码加同一个锁。保证对共享数据操作的完整性。

2.对不同线程操作共享数据的顺序有要求:::使用标记(这个标记定义在资源中,共享)

只有两个线程(一对一):if

class Res

{

private String name;

private String sex;

private  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(int i)

{

if(!flag)

{

try{this.wait();}catch(Exception e){}

}

System.out.println(i+"    "+name+".........."+sex);

flag=false;

this.notify();

}

}

3.有顺序要求。多对多。while(flag)

class Resource

{

private String name;

private int count=1;

private boolean flag=false;

private Lock lock=new ReentrantLock();

private Condition condition_pro=lock.newCondition();

private Condition condition_con=lock.newCondition();

public void set(String name) throws Exception

{

lock.lock();

try

{

while(flag)

condition_pro.await();

this.name=name+"--"+count++;

System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);

flag=true;

condition_con.signal();

}

finally

{

lock.unlock();

}

}

public void out() throws Exception

{

lock.lock();

try

{

while(!flag)

condition_con.await();

System.out.println(Thread.currentThread().getName()+"......消费者......"+this.name);

flag=false;

condition_pro.signal();

}

finally

{

lock.unlock();

}

}

}

线程池:线程运行的时候,内存中会建立一个线程池。等待线程都存在线程池当中。notify唤醒线程池中的第一个线程。

线程wait后,就会进入线程池。

时间: 2024-08-10 11:06:58

多线程问题的思路与处理方式。的相关文章

多线程06-多线程共享数据的方式(经验小结)

1.案例分析-01 通过代码实现火车票出售的例子 在实现代码之前先对问题进行分析:火车票出售应该是在多个窗口进行的(即多个线程),以一个车的班次来说,该班次的火车票张数即为多个窗口共享的数据 即这份共享数据为出售特定班次的火车票,这个动作在多个窗口都是不变的,变更的只有火车票的剩余张数.代码实现如下: package org.lkl.thead; /** * * Function : 多线程共享数据 * * @author : Liaokailin CreateDate : 2014-6-13

回顾一下synchronized关键字,多线程编程的思路

写过 JAVA 并发代码的同学对 synchronized 关键字一定是熟的不能再熟了,其基于对象头部的 monitor 实现了对代码块的加锁,使一段代码变为线程不可重入的. synchronized 与操作系统层的 lock 与 unlock 机制非常类似,多线程通过一个共享变量通信,这个共享变量标志着一段代码是否正在被一段线程执行着,如果已有线程在执行这段代码了,那么其它线程便等待在这个信号量上,直到其执行完毕并重置信号量. 操作系统层级实现 lock/unlock 有两种方式,一是单核环境

Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景

java的同步机制,大概是通过:1.synchronized:2.Object方法中的wait,notify:3.ThreadLocal机制来实现的, 其中synchronized有两种用法:1.对类的方法进行修饰2.synchronized(对象)的方法进行修饰 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量.这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大.

多线程访问共享对象和数据的方式

在多线程访问共享对象和数据时候大致可以分为两大类. 1:如果每个线程执行的代码相同,可以使用同一个runnable对象,这个runnable对象中有那个共享对象.如:买票系统. 1 public class MulteThreadlShareData { 2 public static void main(String[] args) { 3 ShareData shareData = new ShareData(); 4 new Thread(shareData).start(); 5 new

ios开发网络学习五:MiMEType ,多线程下载文件思路,文件的压缩和解压缩

一:MiMEType:一般可以再百度上搜索到相应文件的MiMEType,或是利用c语言的api去获取文件的MiMEType : //对该文件发送一个异步请求,拿到文件的MIMEType - (void)MIMEType { //    NSString *file = @"file:///Users/文顶顶/Desktop/test.png"; [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[

多线程常见的3中实现方式

1.继承Thread类 源代码: package com.zy.test.www.multiThread; /** * 多线程实现方式1:继承Thread类 * @author zy */ public class ByExtendsThread extends Thread{ public ByExtendsThread(String name) { super(name); } @Override public void run() { System.out.println(getName(

Cocos2d-x 3.x中的多线程基本实现思路

当前正在改写一个基于早期Cocos2d-x 2.x实现的小游戏,在涉及到多线程代码时,忽然编译器提示找不到头文件pthread.h.查了一下,发现如今的3.x中不再支持pthread.h头文件,以前的2.X时代这个文件包含在$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread路径下. 现在,3.X中推荐直接使用std::thread相关API,当然是经过C++ 11简化处理后的多线程API. 总体使用思路归纳如下: ----

python并发编程:多线程-开启线程的两种方式

一 threading模块介绍 multiprocess模块完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 二 开启线程的两种方式 方式一 from threading import Thread import time def sayhi(name): time.sleep(2) print("%s say hello" % name) if __name__ == '__main__': t = Thread(target=sayhi, args=('mik

java多线程---创建线程的几种方式

创建线程的几种方式 在并发编程中,创建线程是我们经常会做的事情,那么一般来说,创建线程有4种方式: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callable接口,结合FutureTask来使用. 4.利用线程池的方式来实现. 继承Thread创建线程 public class ThreadTest1 extends Thread { @Override public void run() { try { Thread.sleep(1000); } catch (Inte