java多线程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java多线程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2722字,纯文字阅读大概需要4分钟。
内容图文
![java多线程](/upload/InfoBanner/zyjiaocheng/848/d593025ffd6e421f9637122a2ec73a99.jpg)
synchronized
用法:修饰方法或者修饰代码块
锁定方法:
- 修饰普通方法——相当于修饰代码块(锁定的是this对象)
每个对象都有一个锁,对一个对象加锁,线程在执行的时候,去堆内存中请求该对象的锁(和对象的数据结构一样保存在堆中),
* 获取到该对象的锁之后才能执行内部代码,相当于互斥锁
public class T2 {
private int count=10;
public void f1(){
synchronized(this){ //任何的线程需要执行下面代码,都需要获取this这个对象的锁
count--;
System.out.println(Thread.currentThread().getName() + "count= "+ count);
}
}
//下面这个写法效果一样
public synchronized void f2(){
count--;
System.out.println(Thread.currentThread().getName() + "count= "+count);
}
}
- 修饰静态方法——锁定该类的class对象
public class T3 {
private static int count=10;
public static synchronized void f1(){
count--;
System.out.println("...");
} //当锁定一个静态方法的时候 相当于锁定该类的class对象(反射产生的)
//相当于如下操作
public static void f2(){
//这里不可用写synchronized(this),因为静态的方法是先产生的,不需要产生对象就可以访问
synchronized(T3.class){
count--;
System.out.println("....");
}
}
}
性质
- 原子性
synchronized具有原子性,一个完成的操作不可分。
在没有对run()进行加锁的情况下,会出现重复的值——因为没有加锁,所以多个线程同时运行,出现的结果不唯一。
但是在加锁之后,一次只能有一个线程执行run()方法,所以输出的结果是9 8 7 6 5
/*
Thread0count= 9
Thread3count= 8
Thread2count= 7
Thread1count= 6
Thread4count= 5
这里Thread的名字并不是按照0 1 2 3 4 这样排的,因为一次性创建了5个线程,但是这些线程谁获取到该对象的锁并且执行run()方法,完全是由cpu调度来决定的,这个具有随机性。
*/
public class T4 implements Runnable{
private int count=10;
public /*synchronized */void run(){
count--;
System.out.println(Thread.currentThread().getName() + "count= " + count);
}
public static void main(String[] args) {
T4 t=new T4();
for (int i=0;i<5;i++){
new Thread(t,"Thread"+i).start(); //因为没有对run方法加锁,输出的结果有重复的情况
}
}
}
- 非同步方法和同步方法可以同时调用
同步方法是需要获取到该对象的锁,但是非同步方法并不需要获取该对象的锁,因而是没有影响的。
一个比喻:比如说同步方法就相当于是上厕所,需要获得厕所门的锁,但是非同步方法就好比是在厕所坑外面清洁的人,并不需要获取厕所门的锁。
public class T5 {
public synchronized void f1(){ //锁定普通的方法 就相当于 synchronized(this) 锁定该对象 也就是t
System.out.println(Thread.currentThread().getName() + "m1 start....");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "m1 end .....");
}
public void f2(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "m2 end...." );
}
public static void main(String[] args) {
T5 t=new T5();
new Thread(()->t.f1(),"t1").start();
new Thread(()->t.f2(),"t2").start();
}
}
内容总结
以上是互联网集市为您收集整理的java多线程全部内容,希望文章能够帮你解决java多线程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。