public class Test implements Runnable { int i=1; @Override public synchronized void run() { // TODO Auto-generated method stub System.out.println(i++ +"---------"+Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Test t = new Test(); for(int i=0;i<100;i++){ new Thread(t).start(); } } }
//按照我理解的意思(3)写的代码 public class PrintN { private final int N; private final Thread[] group; private final Object lock = new Object(); private int number = 0; private volatile boolean running = false;
public PrintN(int N){ this.N=N; this.group = new Thread[N]; for(int i=0;i<N;i++){ group[i] = new Printer(); } } private int nextNumber(){ int next = 0; synchronized (lock) { next = number++; if(number>=N){ number = 0; } } return next; } class Printer extends Thread{ public void run(){ while(running){ int n = nextNumber(); System.out.println(Thread.currentThread().getName()+"\t"+n); try { Thread.sleep(1); } catch (InterruptedException e) {break;} } } } public void start(){ if(running==false){ running=true; for(Thread t : group){ t.start(); } } } public void stop(){ if(running){ running=false; } } public static void main(String[] args) throws InterruptedException { PrintN p = new PrintN(10); p.start(); Thread.sleep(5*1000); p.stop(); }}
int i=1;
@Override
public synchronized void run() {
// TODO Auto-generated method stub
System.out.println(i++ +"---------"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test t = new Test();
for(int i=0;i<100;i++){
new Thread(t).start();
}
}
}
其次,问题有歧义。
1. N个线程,每个线程都分别打印 0~N-1 这N个数。
2. N个线程,只要打印 0~N-1 这个范围内的数就行。
3. N个线程,打印的是 0~N-1 范围内的数,但是,要一轮一轮的来,每轮都从 0~N-1 当中取,哪个线程抢到数字就打印哪个,数字不分先后。
4. N个线程,模拟单个线程输出 0~N-1 这几个数。
public class PrintN { private final int N;
private final Thread[] group;
private final Object lock = new Object();
private int number = 0;
private volatile boolean running = false;
public PrintN(int N){
this.N=N;
this.group = new Thread[N];
for(int i=0;i<N;i++){
group[i] = new Printer();
}
}
private int nextNumber(){
int next = 0;
synchronized (lock) {
next = number++;
if(number>=N){
number = 0;
}
}
return next;
}
class Printer extends Thread{
public void run(){
while(running){
int n = nextNumber();
System.out.println(Thread.currentThread().getName()+"\t"+n);
try {
Thread.sleep(1);
} catch (InterruptedException e) {break;}
}
}
}
public void start(){
if(running==false){
running=true;
for(Thread t : group){
t.start();
}
}
}
public void stop(){
if(running){
running=false;
}
}
public static void main(String[] args) throws InterruptedException {
PrintN p = new PrintN(10);
p.start();
Thread.sleep(5*1000);
p.stop();
}}
* 多线程协作问题,每个线程分别打印自己的序号。<p/>
* 由于是多个线程顺次打印,所以,执行效率没有单个线程的高。
*/
public class Printer {
/** 打印令牌,只有拿到令牌的线程才能打印 */
private final Object printToken = new Object();
/** 所有的打印线程 */
private LocalThread [] printThreads;
/** 执行状态 */
private volatile boolean running = false;
/** 创建线程数组,分配各自线程的序号 */
public Printer(int number){
printThreads = new LocalThread[number];
for(int index = 0 ;index<number; index++){
printThreads[index] = new LocalThread();
printThreads[index].index = index;
printThreads[index].token = null;
}
}
/** 开始执行 */
public void start(){
if(!running){
running = true;
for(LocalThread lt : printThreads){
lt.start();
}
//给第一个线程放置打印令牌,之后,唤醒所有线程。
printThreads[0].token = printToken;
synchronized (printToken) {
printToken.notifyAll();
}
}
}
/** 停止执行 */
public void stop(){
if(running){
running = false;
//将所有处于等待状态的线程强制打扰,之后,线程代码抛出异常,结束运行。
for(LocalThread lt : printThreads){
lt.interrupt();
}
}
}
/** 获得下一个应该得到令牌的线程 */
LocalThread getNextThread(int index){
if(++index>=printThreads.length || index<0){
index=0;
}
return printThreads[index];
}
class LocalThread extends Thread{
int index;
Object token;
public void run(){
try {
while(running){
//查看自己是否获得令牌,如果没有令牌则等待
synchronized (printToken) {
while(token==null){
printToken.wait();
}
}
//进行打印
print();
//传递令牌
synchronized (printToken) {
LocalThread next = getNextThread(index);
next.token = printToken;
this.token = null;
printToken.notifyAll();
}
}
} catch (InterruptedException e) {
if(running){
e.printStackTrace();
}
}
}
/** 打印操作 */
protected void print() {
System.out.println(Thread.currentThread().getName()+'\t'+index);
}
} /**
* 测试用例
*/
public static void main(String[] args) throws Exception {
Printer printer = new Printer(10);
printer.start();
Thread.sleep(3000);
printer.stop();
}}
* 多线程协作问题,每个线程分别打印自己的序号。<p/>
* 这个代码是改进后的,效率比上一个版本略微高一点点。<br/>
* 由于是多个线程顺次打印,所以,执行效率依然没有单个线程的高。
*/
public class Printer {
/** 所有的打印线程 */
private LocalThread [] printThreads;
/** 执行状态 */
private volatile boolean running = false;
/** 创建线程数组,分配各自线程的序号 */
public Printer(int number){
printThreads = new LocalThread[number];
for(int index = 0 ;index<number; index++){
printThreads[index] = new LocalThread();
printThreads[index].index = index;
}
}
/** 开始执行 */
public void start(){
if(!running){
running = true;
for(LocalThread lt : printThreads){
lt.start();
}
//唤醒一个线程。
synchronized (printThreads[0].printLock) {
printThreads[0].printLock.notify();
}
}
}
/** 停止执行 */
public void stop(){
if(running){
running = false;
//将所有处于等待状态的线程强制打扰,之后,线程代码抛出异常,结束运行。
for(LocalThread lt : printThreads){
lt.interrupt();
}
}
}
/** 获得下一个应该得到令牌的线程 */
LocalThread getNextThread(int index){
if(++index>=printThreads.length || index<0){
index=0;
}
return printThreads[index];
}
class LocalThread extends Thread{
int index;
/** 打印锁,每个线程有自己的打印锁,每个线程先等待,被唤醒后进行打印。 */
final Object printLock = new Object();
public void run(){
try {
while(running){
//先进入等待状态,等待被唤醒
synchronized (printLock) {
printLock.wait();
}
//进行打印
print();
//唤醒下一个线程
LocalThread next = getNextThread(index);
synchronized (next.printLock) {
next.printLock.notify();
}
}
} catch (InterruptedException e) {
if(running){
e.printStackTrace();
}
}
}
/** 打印操作 */
protected void print() {
System.out.println(Thread.currentThread().getName()+'\t'+index);
}
} /**
* 测试用例
*/
public static void main(String[] args) throws Exception {
Printer printer = new Printer(10);
printer.start();
Thread.sleep(3000);
printer.stop();
}}
public class Test {
private static int NUM = 0;
public static final Object lock = new Object(); public static void main(String[] args) {
for (int i = 10; i >= 0; i--) {
new MyThread(i).start();
}
synchronized (lock) {
lock.notifyAll();
}
} static class MyThread extends Thread {
private int num; public MyThread(int num) {
this.num = num;
} public void run() {
while (NUM < num) {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
System.out.println(num);
NUM++;
synchronized (lock) {
lock.notifyAll();
}
}
}
}