大家好,我有一个浅显的线程问题。求解答。class A{
private int counter;
public void incrementCounter(){
counter++;
}
public int getCounter(){
return counter;
}
}class B{
public doStuff(A a){
int tmp = a.getCounter();
if(tmp < 100){
a.incrementCounter();
}
//do something else
}
}我有两个这样的class 。请问怎样保证doStuff是线程安全才是最好的?我应该在doStuff里synchronize a吗?谢谢!
private int counter;
public void incrementCounter(){
counter++;
}
public int getCounter(){
return counter;
}
}class B{
public doStuff(A a){
int tmp = a.getCounter();
if(tmp < 100){
a.incrementCounter();
}
//do something else
}
}我有两个这样的class 。请问怎样保证doStuff是线程安全才是最好的?我应该在doStuff里synchronize a吗?谢谢!
解决方案 »
- ClassNotFound error分析。。。。。。。。。。。。。。。
- 如何使用JInternalFrame?
- Java开发MP3播放器
- 怎么在applet里跳出一个dialog,我用awt的,不行啊,附上我的部分代码,谢谢
- 求救!——socket文件传输+消息验证传输正确性。(附代码)
- 大虾们来帮我看看怎么会有这种运行结果
- 刚开始学习JAVA,还不太清楚JAVA虚拟机是什么?所谓的虚拟机JVM究竟是因何得来的?哪位告知不胜感激!
- gtfcccq thanks for your jbuilder sn
- 为什么我设置JPanel的Bounds后,不能看到,而抛出异常?请帮忙,谢谢!
- 帮忙给几JAVA技术网站最好都是中文的!!!!!
- 求思路解决这个程序运行导致CPU占用率飙高的问题
- java操作properties文件${}
package com.zhyea;class A {
private int counter; public void incrementCounter() {
counter++;
} public int getCounter() {
return counter;
}
}class B {
public synchronized void doStuff(A a) {
int tmp = a.getCounter();
if (tmp < 100) {
a.incrementCounter();
}
//do something else
}
}关键是同步监视器的控制范围,同步方法的同步监视器是this,如果类里面只有一个同步方法,那么那么使用同步代码块还是同步方法影响不大。再者,如果涉及到了多读少写这样特殊的需求,可以考虑使用Lock
int tmp = a.getCounter();
if(tmp < 100){
synchronized (a) {
if(a.getCounter() < 100){
a.incrementCounter();
}
}
}
//do something else
}
public void doStuff(A a) {
synchronized(a){
int tmp = a.getCounter();
if (tmp < 100) {
a.incrementCounter();
}
}
//do something else
}
}是不是我就可以用不同的thread,作用于不同的a,执行这个dostuff?不好意思初学者,可能没有讲清楚。
public void doStuff(A a) {
synchronized(a){
int tmp = a.getCounter();
if (tmp < 100) {
a.incrementCounter();
}
}
//do something else
}
}是不是我就可以用不同的thread,作用于不同的a,执行这个dostuff?不好意思初学者,可能没有讲清楚。应该是可以的。减小同步控制的作用域,可以提高程序的灵活度
public void doStuff(A a) {
synchronized(a){
int tmp = a.getCounter();
if (tmp < 100) {
a.incrementCounter();
}
}
//do something else
}
}是不是我就可以用不同的thread,作用于不同的a,执行这个dostuff?不好意思初学者,可能没有讲清楚。应该是可以的。减小同步控制的作用域,可以提高程序的灵活度只要明确竞争资源是哪个就好了。
doStuff方法中唯一可能共用的是a,其他都是私有变量,不存在共用。
如果list中的A可能同时被多个线程操作,这需要加同步或锁,否则不需要。其次,如果要加锁,可以这么做,最大限度的减少同步代码作用域及访问次数。class B {
public void doStuff(A a) {
if (a.getCounter() < 100){
// 两次判断,第一次是为了避免,count大于100时,无效地进入同步代码块。
synchronized(a){
if (a.getCounter() < 100) {
// 第二个判断是为了确保值的准确性,可能在进入第一个判断后,另一个线程将count的值++到100了。
a.incrementCounter();
}
}
}
//do something else
}
}
第一段,在方法上加锁:package com.zhyea.test;/**
* @ClassName: MyThread
* @Description: 自己实现的多线程类
* @Site: www.zhyea.com
* @author robin
* @date 2016年2月6日 下午4:06:50
*/
public class MyThread implements Runnable { private static Integer count = 0; @Override
public synchronized void run() {
for (int i = 0; i < 1000; i++) {
++count;
}
} public void test() throws Exception {
MyThread mt = new MyThread();
new Thread(mt, "+++++++ 线程 A ").start();
new Thread(mt, "------- 线程 B ").start();
new Thread(mt, "******* 线程 C ").start();
Thread.sleep(1000L);
System.out.println("-------" + count);
} public static void main(String[] args) throws Exception {
new MyThread().test();
}
}第二段,在竞争属性上加锁:package com.zhyea.test;/**
* @ClassName: MyThread
* @Description: 自己实现的多线程类
* @Site: www.zhyea.com
* @author robin
* @date 2016年2月6日 下午4:06:50
*/
public class MyThread implements Runnable { private static Integer count = 0; @Override
public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (count) {
++count;
}
}
} public void test() throws Exception {
MyThread mt = new MyThread();
new Thread(mt, "+++++++ 线程 A ").start();
new Thread(mt, "------- 线程 B ").start();
new Thread(mt, "******* 线程 C ").start();
Thread.sleep(1000L);
System.out.println("-------" + count);
} public static void main(String[] args) throws Exception {
new MyThread().test();
}
}执行一下这两段就能发现区别。你那个程序中,如果要保证a的同步处理,需要保证a的获取和操作整个过程都是原子性的,将a作为加锁条件不能实现预期的目标。