
正文
java消费者同步代码块 java同步代码快
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
java中同步有几种方式啊
1。同步代码块:
synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。
2。
同步方法:
public synchronized 数据返回类型 方法名(){}
就
是使用 synchronized 来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是
this
也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
1,不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。
2,如果可变类有两种运行环境,当线程环境和多线程环境则应该为该可变类提供两种版本:线程安全版本和线程不安全版本(没有同步方法和同步块)。在单线程中环境中,使用线程不安全版本以保证性能,在多线程中使用线程安全版本.
线程通讯:
为什么要使用线程通讯?
当
使用synchronized
来修饰某个共享资源时(分同步代码块和同步方法两种情况),当某个线程获得共享资源的锁后就可以执行相应的代码段,直到该线程运行完该代码段后才释放对该
共享资源的锁,让其他线程有机会执行对该共享资源的修改。当某个线程占有某个共享资源的锁时,如果另外一个线程也想获得这把锁运行就需要使用wait()
和notify()/notifyAll()方法来进行线程通讯了。
Java.lang.object 里的三个方法wait() notify() notifyAll()
wait方法导致当前线程等待,直到其他线程调用同步监视器的notify方法或notifyAll方法来唤醒该线程。
wait(mills)方法
都是等待指定时间后自动苏醒,调用wait方法的当前线程会释放该同步监视器的锁定,可以不用notify或notifyAll方法把它唤醒。
notify()
唤醒在同步监视器上等待的单个线程,如果所有线程都在同步监视器上等待,则会选择唤醒其中一个线程,选择是任意性的,只有当前线程放弃对该同步监视器的锁定后,也就是使用wait方法后,才可以执行被唤醒的线程。
notifyAll()方法
唤醒在同步监视器上等待的所有的线程。只用当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程
相关问答
Q1: java中什么同步什么是异步分别用在什么地方
java同步指的是synchronized机制,而非synchronized的都是异步,弄懂同步的概念就大致明白了两者的差别。
有关同步:
synchronized用来修饰一个方法或者一个代码块,它用来保证在同一时刻最多只有一个线程执行该段代码。
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
五、以上规则对其它对象锁同样适用。
示例代码:
public class Thread1 implements Runnable {
public void run() {
synchronized(this) {
for (int i = 0; i 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");
ta.start();
tb.start();
}
}
结果:
A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
Q2: java 中同步方法和同步代码块的区别详解
在Java语言中java消费者同步代码块,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上java消费者同步代码块的锁。synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁)。
问题的由来java消费者同步代码块:
看到这样一个面试题:
?
1
2
3
4
5
6
//下列两个方法有什么区别
public synchronized void method1(){}
public void method2(){
synchronized (obj){}
}
synchronized用于解决同步问题java消费者同步代码块,当有多条线程同时访问共享数据时,如果进行同步,就会发生错误,Java提供的解决方案是:只要将操作共享数据的语句在某一时段让一个线程执行完,在执行过程中,其他线程不能进来执行可以。解决这个问题。这里在用synchronized时会有两种方式,一种是上面的同步方法,即用synchronized来修饰方法,另一种是提供的同步代码块。
这里总感觉怪怪的,这两种方法有什么区别呢,基础学得不好,于是就动手做java消费者同步代码块了个简单的测试,代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class SynObj {
public synchronized void methodA() {
System.out.println("methodA.....");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void methodB() {
synchronized(this) {
System.out.pritntln("methodB.....");
}
}
public void methodC() {
String str = "sss";
synchronized (str) {
System.out.println( "methodC.....");
}
}
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class TestSyn {
public static void main(String[] args) {
final SynObj obj = new SynObj();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
obj.methodA();
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
obj.methodB();
}
});
t2.start();
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
obj.methodC();
}
});
t3.start();
}
}
这段小代码片段打印结果如下:
?
1
2
3
4
methodA.....
methodC.....
//methodB会隔一段时间才会打印出来
methodB.....
这段代码的打印结果是,methodA…..methodC…..会很快打印出来,methodB…..会隔一段时间才打印出来,那么methodB为什么不能像methodC那样很快被调用呢?
在启动线程1调用方法A后,接着会让线程1休眠5秒钟,这时会调用方法C,注意到方法C这里用synchronized进行加锁,这里锁的对象是str这个字符串对象。但是方法B则不同,是用当前对象this进行加锁,注意到方法A直接在方法上加synchronized,这个加锁的对象是什么呢?显然,这两个方法用的是一把锁。
*由这样的结果,我们就知道这样同步方法是用什么加锁的了,由于线程1在休眠,这时锁还没释放,导致线程2只有在5秒之后才能调用方法B,由此,可知两种加锁机制用的是同一个锁对象,即当前对象。
另外,同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁,很明显,同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差,一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好。
Q3: Java的synchronized的同步代码块和同步方法的区别
同步代码块是并发的时候锁定一个代码块只能一个线程占用,同步方法是对方法的锁定,如果能同步代码块尽量不要同步方法,否则影响效率
java消费者同步代码块的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java同步代码快、java消费者同步代码块的信息别忘了在本站进行查找喔。







