包含进程同步实验代码java的词条

java实现进程同步读-写互斥:加个boolean writeFlag = false;写的时候保持该值为true,有读操作的时候判断该值是否为false,否则等待读 。
读者优先的附加限制:即多个读操作可以同时进行 。
写者优先的附加限制:设置线程的优先级,保持写的线程优先级始终高于读线程的优先级 。
JAVA 怎么实现多进程同步你好 , 在Java中实现多个进程同步方法有两种 , 我就介绍通过继承Thread来实现线程来举例吧!第一种,创建一个Thread类的子类,在里面重写一个run()方法 , 然后在主线程main()方法里面创建几个类的对象,一个对象代表一个线程,然后通过start()方法启动线程 。第二种,创建多个Thread类的子类,在里面重写一个run()方法,然后在主线程main()方法里面创建这些类的对象,一个对象代表一个线程 , 然后通过start()方法启动线程 。两者的区别:第一种是多个线程同步完成一个任务,比如买票,第二种是不同线程完成不同的任务 。intertupt()方法用来“吵醒”休眠的线程,sleep()方法让进程处于睡眠状态 。答案不满意可以追问,想交流可以加我QQ:460148261,可以一起讨论 。
关于JAVA进程的同步问题 代码如下 为什么运行后只有一个线程工作?麻烦楼上的哥哥们不要误人子弟进程同步实验代码java了进程同步实验代码java , 不能结束的原因是你的线程里没有跳出while(true)的语句也就是没有进程的结束处理,应该if后边else{break;},而为什么都是一个线程调用的就是CPU分配时间片的问题了 , 在代码里加上sleep()处理下结果就明显了
java多线程有几种实现方法?线程之间如何同步一、为什么要线程同步
因为当我们有多个线程要同时访问一个变量或对象时 , 如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常 。举个例子,如果一个银行账户同时被两个线程操作 , 一个取100块,一个存钱100块 。假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个呢?很难说清楚 。因此多线程同步就是要解决这个问题 。
二、不同步时的代码
Bank.Java
package threadTest;
/**
* @author ww
*
*/
public class Bank {
private int count =0;//账户余额
//存钱
publicvoid addMoney(int money){
count=money;
System.out.println(System.currentTimeMillis() "存进:" money);
}
//取钱
publicvoid subMoney(int money){
if(count-money0){
System.out.println("余额不足");
return;
}
count -=money;
System.out.println( System.currentTimeMillis() "取出:" money);
}
//查询
public void lookMoney(){
System.out.println("账户余额:" count);
}
}
SyncThreadTest.java
package threadTest;
public class SyncThreadTest {
public static void main(String args[]){
final Bank bank=new Bank();
Thread tadd=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bank.addMoney(100);
bank.lookMoney();
System.out.println("\n");
}
}
});
Thread tsub = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
bank.subMoney(100);
bank.lookMoney();
System.out.println("\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
tsub.start();
tadd.start();
}
}
余额不足
账户余额:0
余额不足
账户余额:100
1441790503354存进:100
账户余额:100
1441790504354存进:100
账户余额:100
1441790504354取出:100
账户余额:100
1441790505355存进:100
账户余额:100
1441790505355取出:100
账户余额:100
三、使用同步时的代码
(1)同步方法:
即有synchronized关键字修饰的方法 。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法 。在调用该方法前,需要获得内置锁,否则就处于阻塞状态 。
修改后的Bank.java
package threadTest;
/**
* @author ww
*
*/
public class Bank {
private int count =0;//账户余额
//存钱
publicsynchronized void addMoney(int money){
count=money;
System.out.println(System.currentTimeMillis() "存进:" money);
}
//取钱
publicsynchronized void subMoney(int money){
if(count-money0){
System.out.println("余额不足");
return;
}
count -=money;
System.out.println( System.currentTimeMillis() "取出:" money);
}
//查询
public void lookMoney(){
System.out.println("账户余额:" count);
}
}
再看看运行结果:
余额不足
账户余额:0
余额不足
账户余额:0
1441790837380存进:100
账户余额:100
1441790838380取出:100
账户余额:0
1441790838380存进:100
账户余额:100
1441790839381取出:100
账户余额:0
瞬间感觉可以理解了吧 。
注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法 , 将会锁住整个类
(2)同步代码块
即有synchronized关键字修饰的语句块 。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
Bank.java代码如下:
package threadTest;
/**
* @author ww
*
*/
public class Bank {
private int count =0;//账户余额
//存钱
publicvoid addMoney(int money){
synchronized (this) {
count=money;
}
System.out.println(System.currentTimeMillis() "存进:" money);
}
//取钱
publicvoid subMoney(int money){
synchronized (this) {
if(count-money0){
System.out.println("余额不足");
return;
}
count -=money;
}
System.out.println( System.currentTimeMillis() "取出:" money);
}
//查询
public void lookMoney(){
System.out.println("账户余额:" count);
}
}
运行结果如下:
余额不足
账户余额:0

1441791806699存进:100
账户余额:100

1441791806700取出:100
账户余额:0

1441791807699存进:100
账户余额:100
效果和方法一差不多 。
注:同步是一种高开销的操作 , 因此应该尽量减少同步的内容 。通常没有必要同步整个方法 , 使用synchronized代码块同步关键代码即可 。
(3)使用特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
Bank.java代码如下:
package threadTest;
/**
* @author ww
*
*/
public class Bank {
private volatile int count = 0;// 账户余额
// 存钱
public void addMoney(int money) {
count= money;
System.out.println(System.currentTimeMillis()"存进:"money);
}
// 取钱
public void subMoney(int money) {
if (count - money0) {
System.out.println("余额不足");
return;
}
count -= money;
System.out.println( System.currentTimeMillis()"取出:"money);
}
// 查询
public void lookMoney() {
System.out.println("账户余额:"count);
}
}
运行效果怎样呢?
余额不足
账户余额:0
余额不足
账户余额:100
1441792010959存进:100
账户余额:100
1441792011960取出:100
账户余额:0
1441792011961存进:100
账户余额:100
是不是又看不懂了,又乱了 。这是为什么呢?就是因为volatile不能保证原子操作导致的,因此volatile不能代替synchronized 。此外volatile会组织编译器对代码优化 , 因此能不使用它就不适用它吧 。它的原理是每次要线程要访问volatile修饰的变量时都是从内存中读?。皇谴婊捍娴敝卸寥 。虼嗣扛鱿叱谭梦实降谋淞恐刀际且谎?。这样就保证了同步 。
(4)使用重入锁实现线程同步
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步 。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和快具有相同的基本行为和语义 , 并且扩展了其能力 。
ReenreantLock类的常用方法有:
ReentrantLock() : 创建一个ReentrantLock实例
lock() : 获得锁
unlock() : 释放锁
注:ReentrantLock()还有一个可以创建公平锁的构造方法 , 但由于能大幅度降低程序运行效率 , 不推荐使用
Bank.java代码修改如下:
package threadTest;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author ww
*
*/
public class Bank {
privateint count = 0;// 账户余额
//需要声明这个锁
private Lock lock = new ReentrantLock();
// 存钱
public void addMoney(int money) {
lock.lock();//上锁
try{
count= money;
System.out.println(System.currentTimeMillis()"存进:"money);
}finally{
lock.unlock();//解锁
}
}
// 取钱
public void subMoney(int money) {
lock.lock();
try{
if (count - money0) {
System.out.println("余额不足");
return;
}
count -= money;
System.out.println( System.currentTimeMillis()"取出:"money);
}finally{
lock.unlock();
}
}
// 查询
public void lookMoney() {
System.out.println("账户余额:"count);
}
}
运行效果怎么样呢?
余额不足
账户余额:0
余额不足
账户余额:0
1441792891934存进:100
账户余额:100
1441792892935存进:100
账户余额:200
1441792892954取出:100
账户余额:100
效果和前两种方法差不多 。
如果synchronized关键字能满足用户的需求,就用synchronized,因为它能简化代码。如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁 , 否则会出现死锁 , 通常在finally代码释放锁
(5)使用局部变量实现线程同步
Bank.java代码如下:
package threadTest;
/**
* @author ww
*
*/
public class Bank {
private static ThreadLocalInteger count = new ThreadLocalInteger(){
@Override
protected Integer initialValue() {
// TODO Auto-generated method stub
return 0;
}
};
// 存钱
public void addMoney(int money) {
count.set(count.get() money);
System.out.println(System.currentTimeMillis()"存进:"money);
}
// 取钱
public void subMoney(int money) {
if (count.get() - money0) {
System.out.println("余额不足");
return;
}
count.set(count.get()- money);
System.out.println( System.currentTimeMillis()"取出:"money);
}
// 查询
【包含进程同步实验代码java的词条】 public void lookMoney() {
System.out.println("账户余额:"count.get());
}
}
运行效果:
余额不足
账户余额:0
余额不足
账户余额:0
1441794247939存进:100
账户余额:100
余额不足
1441794248940存进:100
账户余额:0
账户余额:200
余额不足
账户余额:0
1441794249941存进:100
账户余额:300
看了运行效果,一开始一头雾水,怎么只让存,不让取?。靠纯碩hreadLocal的原理:
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立 , 这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响 。现在明白了吧,原来每个线程运行的都是一个副本,也就是说存钱和取钱是两个账户,知识名字相同而已 。所以就会发生上面的效果 。
ThreadLocal与同步机制
a.ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题
b.前者采用以"空间换时间"的方法,后者采用以"时间换空间"的方式
Java如何实现多线程同步?//解决方案-1 设置3把锁, 然后把锁们应用到所有线程中(涉及到synchronized wait notify等, 嫌麻烦. 略)
解决方案-2 设置3个全局共享的信号标记(信号灯)3子线程分别占用标记1 2 3
主线程轮询/等待
(简洁明快 推荐)
//解决方案-2实现如下:
static booleant1_done = false;
static booleant2_done = false;
static booleant3_done = false;
//t1------run() {............ ;t1_done = true; }
//t2、 3: 同理,略
main () { .............;
启动t1;
启动t2;
启动t3;
//轮询 or 等待
while ( true )
if ( t1_donet2_donet3_done)break;
else
Thread.yield () ;
// 或 Thread.sleep(xxxx) ----若子线程运行超过100ms以上,应予考虑
//轮询结束,主线程继续工作
}//main END
have fun
进程同步实验代码java的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、进程同步实验代码java的信息别忘了在本站进行查找喔 。

    推荐阅读