一个有关线程问题的疑惑,比较简单,我是新手,请指教下
如下这段代码,我希望打印0-100,但实际运行还是会产生重复的数,我应该怎么改写代码呢,我已经使用了synchronized关键词啊?
public class Test{
public static void main(String[ ] args) {
ThreadTest a = new ThreadTest();
for(int i=0;i<100;i++){
new Thread(a).start();
a.print();
}
}
}
class ThreadTest implements Runnable {
Count c = new Count();
@Override
public void run() {
c.increase();
}
public void print() {
System.out.println(c.getValue());
}
}
final class Count {
private long value = 0;
public synchronized long getValue() {
return value;
}
public synchronized long increase() {
if(value == Long.MAX_VALUE) {
throw new IllegalStateException("error");
}
return ++value;
}
}
public class Test22{
public static void main(String[ ] args) {
ThreadTest a = new ThreadTest();
for(int i=0;i<100;i++){
new Thread(a).start();
// a.print();
}
}
}
class ThreadTest implements Runnable {
Count c = new Count();
public void run() {
c.increase();
}
// public void print() {
// System.out.println(c.getValue());
// }
}
final class Count {
private long value = 0;
public synchronized long getValue() {
return value;
}
public synchronized long increase() {
if(value == Long.MAX_VALUE) {
throw new IllegalStateException("error");
}
System.out.println(++value);
return value;
}
}
public class VolatileTest {
static Integer count = 0;
static volatile Integer countVolatile = 0;
static Integer countSynchronizedMethod = 0;
static Integer countSynchronizedAttribute = 0;
static void addCount(){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
count ++;
}
static void addCountVolatile(){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countVolatile ++;
}
static synchronized void addCountSynchronizedMethod(){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countSynchronizedMethod ++;
}
static void addCountSynchronizedAttribute(){
synchronized(countSynchronizedAttribute){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countSynchronizedAttribute ++;
}
}
/**
* 功能:
* @param args
*/
public static void main(String[] args) {
ThreadGroup group = new ThreadGroup("test");
for (int i = 0; i < 1000; i++) {
Thread thread = new Thread(group,""){
public void run() {
addCount();
addCountVolatile();
addCountSynchronizedMethod();
addCountSynchronizedAttribute();
}
};
thread.start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count:" + count);
System.out.println("countVolatile:" + countVolatile);
System.out.println("countSynchronized:" + countSynchronizedMethod);
System.out.println("countSynchronizedAttribute:" + countSynchronizedAttribute);
}
}另外,
// 方案1 :同步
public void run() {
synchronized (c) { // 这里是关键,把(动作1,动作2)同步
// 这意味着,在动作1和动作2之间,别的线程插不进来
c.increase(); // 动作1
try {
Thread.currentThread().sleep(100); // Sleep 加强观察效果
} catch (InterruptedException e) {}
System.out.println(c.getValue()); // 动作2
}
}
// 方案2:无同步
public void run() {
c.increase(); // 动作1
try {
Thread.currentThread().sleep(100); // Sleep 加强观察效果
} catch (InterruptedException e) {}
System.out.println(c.getValue()); // 动作2
}
// 方案1 :同步
public void run() {
synchronized (c) {
//...body
}
}
// 等同于:
public synchronized void run() {
//...body
}