×

java多线程有几种实现方法 多线程有几种实现方法 java

java多线程有几种实现方法线程之间如何同步?JAVA中如何产生一个特定范围的随机数

admin admin 发表于2022-07-15 22:55:09 浏览115 评论0

抢沙发发表评论

java多线程有几种实现方法线程之间如何同步

1.为什么线程同步

因为当我们有多个线程可以同时访问变量或对象时,如果这些线程既读写操作又会引起变量值或对象的状态,这将导致程序异常。例如,如果一个银行帐户同时由两个线程运营,则一个元人元,一个元来保存100元。该帐户最初具有0元。如果货币收集和存款线程同时发生,将会发生什么?不成功的钱失败,帐户余额是100。钱成功,帐户余额为0。这是哪一个?很难说?显然,因此,多线程同步是为了解决此问题。

第二,不同的代码

把人.Java

package threadTest;
/**
 * @author ww
 *
 */
public class Bank {
private int count =0;//账户余额

//存钱
public  void addMoney(int money){
count +=money;
System.out.println(System.currentTimeMillis()+“存进:“+money);
}

//取钱
public  void subMoney(int money){
if(count-money 《 0){
System.out.println(“余额不足“);
return;
}
count -=money;
System.out.println(+System.currentTimeMillis()+“取出:“+money);
}

//查询
public void lookMoney(){
System.out.println(“账户余额:“+count);
}
}

同步线程test.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)同步方法:

有一种用于同步关键字的修饰符的方法。bausjava的每个对象都有一个构建-in锁定,当使用此关键字修改方法时,构建的-in锁定将保护整个方法。在调用此方法之前,您需要获取一个锁定的锁,否则您将处于阻止状态。-JAVA

修改后的bank.java


package threadTest;
/**
 * @author ww
 *
 */
public class Bank {
private int count =0;//账户余额

//存钱
public  synchronized void addMoney(int money){
count +=money;
System.out.println(System.currentTimeMillis()+“存进:“+money);
}

//取钱
public  synchronized void subMoney(int money){
if(count-money 《 0){
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

我觉得可以立即理解它。

注意:同步关键字还可以修改静态方法。目前,如果调用了静态方法,则整个类将被锁定

(2)同步代码块

也就是说,有一个由同步关键字修改的句子块。该关键字修改的语句块将自动添加使用构建-in锁定,以实现同步

bank.java代码如下:


package threadTest;
/**
 * @author ww
 *
 */
public class Bank {
private int count =0;//账户余额

//存钱
public   void addMoney(int money){

synchronized (this) {
count +=money;
}
System.out.println(System.currentTimeMillis()+“存进:“+money);
}

//取钱
public   void subMoney(int money){

synchronized (this) {
if(count-money 《 0){
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

效果和方法几乎相同。

注意:同步是一个高成本的操作,因此您应该最大程度地减少同步内容。通常不需要同步整个方法。使用同步代码块同步密钥代码。

(3)使用特殊域变量(挥发性)实现线程同步

A. Volantile关键字提供了用于域变量的访问的无锁机制B.使用挥发性装饰域的使用等同于告诉虚拟机,可以通过其他线程更新域。挥发性不会提供任何原子操作,不能用于修改最终类型的变量

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 - money 《 0) {
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

不能再理解它了。它的原理是,从内存中读取每个线程,以读取挥发性修改的变量,而不是在内存中读取,而不是在缓存中读取,因此每个线程的变量值相同。这保证了同步。

(4)使用重型传入锁实现线程同步

java.util.concurrent软件包被添加到Javase5.0中以支持同步。rentrantlock类是一个可以重复,相互排斥并实现锁定接口的锁。它具有与使用同步方法和快速的基本行为和语义相同的基本行为和语义,并扩大了其能力。reenreantlock类的常见方法为:reentrantlock():创建一个reentrantlock实例lock():获取lock lock unlock():释放锁定注:reentrantlock()还具有可以创建公平锁的结构,但可以大大降低程序。项目效率,不建议使用bank.java代码修改以下内容:-java


package threadTest;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @author ww
 *
 */
public class Bank {
private  int 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 - money 《 0) {
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

效果与前两种方法相似。

如果同步关键字可以满足用户的需求,请使用同步,因为它可以简化代码。如果您需要更多高级功能,请使用Reentrantlock类。目前,您应该注意及时释放锁,否则会出现死锁。通常,您在最后代码上释放锁。

(5)使用局部变量实现线程同步

bank.java代码如下:


package threadTest;

/**
 * @author ww
 *
 */
public class Bank {
private static ThreadLocal《Integer》 count = new ThreadLocal《Integer》(){
@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() - money 《 0) {
System.out.println(“余额不足“);
return;
}
count.set(count.get()- money);
System.out.println(+System.currentTimeMillis() + “取出:“ + money);
}
// 查询
public void lookMoney() {
System.out.println(“账户余额:“ + count.get());
}
}

运行结果:


余额不足
账户余额:0

余额不足
账户余额:0

1441794247939存进:100
账户余额:100

余额不足
1441794248940存进:100
账户余额:0

账户余额:200

余额不足
账户余额:0

1441794249941存进:100
账户余额:300

在观看了跑步效果之后,一开始,我该如何保留它而不让它进行?看ThreadLocal的原理:

如果使用螺纹插座用于管理变量,则使用变量的每个线程从变量的副本中获得,并且该副本彼此独立,因此每个线程可以在WILL上修改其自身变量副本而不会影响其他线程。据了解,每个线程都运行一个副本,这意味着省钱和货币赚钱是两个帐户,相同的知识名称相同。因此,上述效果将发生。-JAVA

螺纹网和同步机制A.ThreadLocal和同步机制是在多线程中解决相同变量中访问冲突的问题

b。

JAVA中如何产生一个特定范围的随机数

在0-2之间生成随机数,包括2

随机rand =新的随机();

int randnum = rand.nextint(3);

生成5-26之间的随机数,包括26

int randNum = rand.nextInt(22)+5;

随机数是在Java中以间隔段生成的:

假设您要生成5到10之间的随机数,可以使用以下方法:

int min = 5;

int max = 10;

int result = Min + (int)(Math.random() * ((Max - Min) + 1));

学java要多少钱培训多长时间


一般培训的费用都在2W左右的,Java培训学习费用多少?Java培训班大概需要多少时间?
选择培训学校最好是搜索好几家信息做信息甄别、对比再做决定,毕竟成本在那里,不多也不会少。培训的价钱具体也不好说,不是所有人都一个价钱 如果说你有一定的基础,在课程选择上可减少那些基础的课程。
一、Java培训学习费用多少?Java培训班大概需要多少钱?
如果是学一些比较系统的网课,那可能报课花费上千元也是很正常的。
学费根据个人基础水平不同会有所波动,Java培训学习周期一般是学习五个月左右的时间,学费大概在是在两万左右。
如果自己真的想要去培训班学习的话,自己一定要事先要了解大概这几个方面:课程、师资、环境、上课氛围、课时(温馨提示有的老师上课的时间才算作课时,有的自习的时间也算作课时)、就业(高薪是指多少? 最少薪资是多少?就业城市有哪些)等等。
当然如果你是零基础人员想要找Java培训的话,你可以自己先自学一段时间,看看自己能不能学的会。关于自学的教程你可以先看杜老师的基础教程进行学习,或者你也可以来动力节点的Java实验班进行测试自己适不适合学习Java,Java实验班可以免费的学习十五天的时间,学习完之后老师来进行专业的测试。
可能你会觉得花费这么多费用学习有点贵或者是不太值得。那也可以选择自学的方法。
对于自学能力强,有耐心,自觉性高的人,那自学完全是有可能的,因为Java也是一门相对简洁的语言,入门起来也会比较容易。
不过,它可能并没有你想象的那么轻松。对于一个零基础的小白来说,是很困难,但是只要你去认真学习,那对你来说真的是不困难。
但自学没有人帮你制定学习计划,传授学习方法,明确学习线路,你可能要把大量的时间花费在寻找学习资料上,还要花大把时间将你学到的知识碎片拼凑在一起,这其中任何一环出现问题,可能都会停滞很长时间。你可能会高估自己的自学能力和自觉性,却很难达到想要的效果,可能学一年都很难达到入职标准。
-java